diff --git a/src/README.md b/src/README.md index dfca4a8f68c6725994c36297aa67d3841a758894..f371a1e68eac3059247fba7a2f00132c76c67b4b 100644 --- a/src/README.md +++ b/src/README.md @@ -63,3 +63,15 @@ 多arch支持 > docker manifest push时Registry Credentials? + +## 目录结构 +| 目录 | 描述 | +| --- | --- | +|ac/framework | 门禁框架 | +|ac/acl | 门禁任务,每个门禁项对应一个目录 | +|ac/common | 门禁通用代码 | +|build| 单包构建| +|jobs| jenkins任务管理| +|conf|配置| +|proxy|第三方接口代理| +|utils|通用代码,日志等| diff --git a/src/ac/acl/package_license/__init__.py b/src/ac/acl/package_license/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..36e95ff3db7d173ff656de1605ce299b4e77f17a --- /dev/null +++ b/src/ac/acl/package_license/__init__.py @@ -0,0 +1,17 @@ +# -*- encoding=utf-8 -*- +""" +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-10-16 +# Description: check spec file +# ********************************************************************************** +""" \ No newline at end of file diff --git a/src/ac/acl/package_license/check_license.py b/src/ac/acl/package_license/check_license.py new file mode 100644 index 0000000000000000000000000000000000000000..b73cdc0d7380de4897cbb22df3b6728465bb569a --- /dev/null +++ b/src/ac/acl/package_license/check_license.py @@ -0,0 +1,116 @@ +# -*- encoding=utf-8 -*- +""" +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-10-16 +# Description: check spec file +# ********************************************************************************** +""" + +import logging +import time +import os +import yaml +import shutil + +from src.proxy.git_proxy import GitProxy +from src.ac.framework.ac_result import FAILED, WARNING, SUCCESS +from src.ac.framework.ac_base import BaseCheck +from src.ac.common.rpm_spec_adapter import RPMSpecAdapter +from src.ac.common.gitee_repo import GiteeRepo +from src.ac.acl.package_license.package_license import PkgLicense + +logger = logging.getLogger("ac") + +class CheckLicense(BaseCheck): + """ + check license in spec and src-code + """ + + def __init__(self, workspace, repo, conf=None): + super(CheckLicense, self).__init__(workspace, repo, conf) + + self._gp = GitProxy(self._work_dir) + self._work_tar_dir = os.path.join(workspace, "code") + self._gr = GiteeRepo(self._repo, self._work_dir, self._work_tar_dir) + if self._gr.spec_file: + self._spec = RPMSpecAdapter(os.path.join(self._work_dir, self._gr.spec_file)) + else: + self._spec = None + + self._pkg_license = PkgLicense() + self._license_in_spec = set() + self._license_in_src = set() + + def check_license_in_spec(self): + """ + check whether the license in spec file is in white list + :return + """ + if self._spec is None: + logger.warning("spec file not find") + return WARNING + self._license_in_spec = self._gr.scan_license_in_spec(self._spec) + self._license_in_spec = self._pkg_license.translate_license(self._license_in_spec) + if self._pkg_license.check_license_safe(self._license_in_spec): + return SUCCESS + else: + logger.warning("licenses in spec are not in white list") + return WARNING + + def check_license_in_src(self): + """ + check whether the license in src file is in white list + :return + """ + self._license_in_src = self._pkg_license.scan_licenses_in_license(self._work_tar_dir) + self._license_in_src = self._pkg_license.translate_license(self._license_in_src) + if not self._license_in_src: + logger.warning("can't find license in src code") + return WARNING + if self._pkg_license.check_license_safe(self._license_in_src): + return SUCCESS + else: + logger.warning("licenses in src code are not in white list") + return WARNING + + def check_license_is_same(self): + """ + check whether the license in spec file and in src file is same + :return + """ + if self._pkg_license.check_licenses_is_same(self._license_in_spec, self._license_in_src): + logger.info("licenses in src:{} and in spec:{} are same".format(self._license_in_src, + self._license_in_spec)) + return SUCCESS + else: + logger.warning("licenses in src:{} and in spec:{} are not same".format(self._license_in_src, + self._license_in_spec)) + return WARNING + + def __call__(self, *args, **kwargs): + """ + 入口函数 + :param args: + :param kwargs: + :return: + """ + logger.info("check {} license ...".format(self._repo)) + + _ = not os.path.exists(self._work_tar_dir) and os.mkdir(self._work_tar_dir) + self._gr.decompress_all() # decompress all compressed file into work_tar_dir + self._pkg_license.load_config() # load license config into instance variable + + try: + return self.start_check_with_order("license_in_spec", "license_in_src", "license_is_same") + finally: + shutil.rmtree(self._work_tar_dir) \ No newline at end of file diff --git a/src/ac/acl/package_license/config/license_list b/src/ac/acl/package_license/config/license_list new file mode 100644 index 0000000000000000000000000000000000000000..13861c91eeee86db0f8ca2ff84114d4b0d7b4e97 --- /dev/null +++ b/src/ac/acl/package_license/config/license_list @@ -0,0 +1,451 @@ +0BSD,white +AAL,white +ADSL,black +AFL, white +AFL-1.1,white +AFL-1.2,white +AFL-2.0,white +AFL-2.1,white +AFL-3.0,white +AFLv2.1, white +AGPL-1.0-only,black +AGPL-1.0-or-later,black +AGPL-3.0, white +AGPL-3.0-only,black +AGPL-3.0-or-later,black +AGPLv3, white +AGPLv3+, white +AMDPLPA,black +AML,black +AMPAS,black +AND, black +ANTLR-PD,black +APAFML,black +APL-1.0,black +APSL-1.0,black +APSL-1.1,black +APSL-1.2,black +APSL-2.0,white +ASL-1.0, white +ASL-1.1, white +ASL-2.0, white +Abstyles,black +Adobe-2006,black +Adobe-Glyph,black +Afmparse,black +Aladdin,black +Apache, white +Apache-1.1,white +Apache-2, white +Apache-2.0,white +Arphic, black +Artistic, white +Artistic-1.0,black +Artistic-1.0-Perl,black +Artistic-1.0-cl8,black +Artistic-2.0,white +BSD, white +BSD-1-Clause,white +BSD-2-Clause,white +BSD-2-Clause-Patent,white +BSD-3-Clause,white +BSD-3-Clause-Attribution,black +BSD-3-Clause-LBNL,black +BSD-3-Clause-No-Nuclear-License,black +BSD-3-Clause-No-Nuclear-License-2014,black +BSD-3-Clause-No-Nuclear-Warranty,black +BSD-3-Clause-Open-MPI,black +BSD-4-Clause-UC,black +BSD-Protection,black +BSD-Source-Code,black +BSD-licenced-3, white +BSD3, white +BSL-1.0,white +Bahyph,black +Barr,black +Beerware,black +BitTorrent-1.0,black +BlueOak-1.0.0,black +Boost, white +Borceux,black +CAL-1.0,black +CAL-1.0-Combined-Work-Exception,black +CATOSL-1.1,white +CC-BY, black +CC-BY-1.0,black +CC-BY-2.0,black +CC-BY-2.5,black +CC-BY-3.0,black +CC-BY-4.0,white +CC-BY-NC-1.0,black +CC-BY-NC-2.0,black +CC-BY-NC-2.5,black +CC-BY-NC-3.0,black +CC-BY-NC-4.0,black +CC-BY-NC-ND-1.0,black +CC-BY-NC-ND-2.0,black +CC-BY-NC-ND-2.5,black +CC-BY-NC-ND-3.0,black +CC-BY-NC-ND-4.0,black +CC-BY-NC-SA-1.0,black +CC-BY-NC-SA-2.0,black +CC-BY-NC-SA-2.5,black +CC-BY-NC-SA-3.0,black +CC-BY-NC-SA-4.0,black +CC-BY-ND-1.0,black +CC-BY-ND-2.0,black +CC-BY-ND-2.5,black +CC-BY-ND-3.0,black +CC-BY-ND-4.0,black +CC-BY-SA, black +CC-BY-SA-1.0,black +CC-BY-SA-2.0,black +CC-BY-SA-2.5,black +CC-BY-SA-3.0,black +CC-BY-SA-4.0,white +CC-PDDC,black +CC0, black +CC0-1.0,white +CDDL, white +CDDL-1.0,white +CDDL-1.1,black +CDLA-Permissive-1.0,black +CDLA-Sharing-1.0,black +CECILL-1.0,black +CECILL-1.1,black +CECILL-2.1,black +CERN-OHL-1.1,black +CERN-OHL-1.2,black +CERN-OHL-P-2.0,black +CERN-OHL-S-2.0,black +CERN-OHL-W-2.0,black +CNRI-Jython,black +CNRI-Python,white +CNRI-Python-GPL-Compatible,black +CPAL-1.0,white +CPL, white +CPL-1.0,white +CPOL-1.02,black +CUA-OPL-1.0,black +Caldera,black +Commons Clause,black +Commons Clause 1.0, white +Crossword,black +CrystalStacker,black +Cube,black +D-FSL-1.0,black +DMIT,black +DMTF, black +DOC,black +DSDP,black +Dotseqn,black +ECL-1.0,black +ECL-2.0,white +EFL-1.0,black +EFL-2.0,white +EPL, white +EPL-1.0,white +EPL-2.0,white +EUDatagrid,white +EUPL-1.0,black +EUPL-1.1,white +EUPL-1.2,white +Entessa,black +ErlPL-1.1,black +Eurosym,black +FSFAP, black +FSFUL,black +FSFULLR,black +FTL, black +Fair,white +Frameworx-1.0,black +FreeImage,black +GFDL-1.1, white +GL2PS,black +GPL, white +GPL+, white +GPL-1.0, white +GPL-1.0+, white +GPL-1.0-only,black +GPL-1.0-or-later,black +GPL-2, white +GPL-2.0, white +GPL-2.0+, white +GPL-2.0-only,white +GPL-2.0-or-later,white +GPL-3.0, white +GPL-3.0+, white +GPL-3.0-only,white +GPL-3.0-or-later,white +GPL2, white +GPLV2, white +GPLV2+, white +GPLv1+, white +GPLv2, white +GPLv2+, white +GPLv2-or-later, white +GPLv3, white +GPLv3+, white +Giftware,black +Glide,black +Glulxe,black +HPND,white +HPND-sell-variant,black +HaskellReport,black +Hippocratic-2.1,black +IBM, black +IBM-pibs,black +ICU,black +IEEE, black +IJG,white +IPA,white +IPL-1.0,white +ISC,white +ImageMagick,black +Info-ZIP,black +Intel,white +Intel-ACPI,black +Interbase, black +Interbase-1.0,black +JPNIC,black +JSON,black +JasPer-2.0,black +Knuth, black +LAL-1.2,black +LAL-1.3,black +LGPL-2.0, white +LGPL-2.0+, white +LGPL-2.0-only,white +LGPL-2.0-or-later,white +LGPL-2.1, white +LGPL-2.1+, white +LGPL-2.1-only,white +LGPL-2.1-or-later,white +LGPL-3.0+, white +LGPL-3.0-only,white +LGPL-3.0-or-later,white +LGPLLR,black +LGPLv2, white +LGPLv2+, white +LGPLv2.1, white +LGPLv2.1+, white +LGPLv3, white +LGPLv3+, white +LPL-1.0,black +LPL-1.02,white +LPPL, white +LPPL-1.0,black +LPPL-1.1,black +LPPL-1.3c,white +Latex2e,black +Leptonica,black +LiLiQ-P-1.1,black +LiLiQ-R-1.1,black +LiLiQ-Rplus-1.1,black +Liberation, black +Libpng,black +Licence-2.0, black +Linux-OpenIB,black +Lucida, black +MIT,white +MIT-0,black +MIT-CMU,black +MIT-advertising,black +MIT-enna,black +MIT-feh,black +MITNFA,black +MPL-1.0,white +MPL-1.1,white +MPL-2, white +MPL-2.0,white +MPL-2.0-no-copyleft-exception,black +MPL2, white +MPLv1.1, white +MPLv2.0, white +MS-PL,white +MS-RL,white +MTLL,black +MakeIndex,black +MirOS,white +Motosoto,white +Mulan 2.0, white +Mulan-PSL-1, white +Mulan-PSL-2, white +MulanPSL-1.0,black +MulanPSL-2.0,white +Multics,black +Mup,black +NASA-1.3,black +NBPL-1.0,black +NCGL-UK-2.0,black +NCSA,white +NGPL,white +NLOD-1.0,black +NLPL,black +NPOSL-3.0,black +NRL,black +NTP,white +NTP-0,black +Naumen,white +Net-SNMP,black +NetCDF,black +Netscape, black +Newsletr,black +Nmap, black +Nokia,white +Noweb,black +O-UDA-1.0,black +OCCT-PL,black +OCLC-2.0,black +ODC-By-1.0,black +OFL, white +OFL-1.0-RFN,black +OFL-1.0-no-RFN,black +OFL-1.1,white +OFL-1.1-RFN,black +OFL-1.1-no-RFN,black +OFSFDL, black +OGC-1.0,black +OGL-Canada-2.0,black +OGL-UK-1.0,black +OGL-UK-2.0,black +OGL-UK-3.0,black +OGTSL,black +OLDAP-1.1,black +OLDAP-1.2,black +OLDAP-1.3,black +OLDAP-1.4,black +OLDAP-2.0,black +OLDAP-2.0.1,black +OLDAP-2.1,black +OLDAP-2.2,black +OLDAP-2.2.1,black +OLDAP-2.2.2,black +OLDAP-2.4,black +OLDAP-2.5,black +OLDAP-2.6,black +OLDAP-2.8,black +OML,black +OPL-1.0,black +OSET-PL-2.1,black +OSL-1.0,white +OSL-2.0,white +OSL-2.1,white +OSL-3.0,white +OpenLDAP, black +OpenSSL,white +PDDL-1.0,black +PHP, white +PHP-3.0,white +PSF, black +PSF-2.0,black +Parity-6.0.0,black +Parity-7.0.0,black +Perl, white +Plexus,black +PolyForm-Noncommercial-1.0.0,black +PolyForm-Small-Business-1.0.0,black +PostgreSQL,white +Pubilc, black +Python, white +Python-2.0,white +QPL, white +QPL-1.0,white +Qhull,black +RHeCos-1.1,black +RPL-1.1,black +RPL-1.5,black +RPSL-1.0,white +RSA-MD,black +RSCPL,black +Rdisc,black +Ruby,white +SAX-PD,black +SCEA,black +SGI-B-1.0,black +SGI-B-1.1,black +SHL-0.5,black +SHL-0.51,black +SISSL,white +SISSL-1.2,black +SMPPL,black +SNIA,black +SPL-1.0,white +SSH-OpenSSH,black +SSH-short,black +SSLeay, black +SSPL-1.0,black +SWL,black +Saxpath,black +Sendmail,black +Sendmail-8.23,black +SimPL-2.0,black +Sleepycat,white +Spencer-86,black +Spencer-94,black +Spencer-99,black +SugarCRM-1.1.3,black +TAPR-OHL-1.0,black +TCGL, black +TCL,white +TCP-wrappers,black +TMate,black +TORQUE-1.1,black +TOSL,black +TTWL, black +TU-Berlin-1.0,black +TU-Berlin-2.0,black +UCD,white +UCL-1.0,black +UPL-1.0,white +Unicode, black +Unicode-DFS-2015,black +Unicode-DFS-2016,black +Unicode-TOU,black +Utopia, black +VOSTROM,black +VSL-1.0,white +Verbatim, black +Vim, black +W3C,white +W3C-19980720,black +W3C-20150513,black +WTFPL, black +Watcom-1.0,black +Wsuipa,black +XSkat,black +Xerox,black +Xnet,black +YPL-1.0,black +ZPL-1.1,black +ZPL-2.0,white +ZPL-2.1,white +ZPLv2.0, white +ZPLv2.1, white +Zed,black +Zimbra-1.4,black +Zlib,white +artistic,black +artistic-2.0,black +blessing,black +bzip2-1.0.5,black +bzip2-1.0.6,black +copyleft-next-0.3.0,black +copyleft-next-0.3.1,black +curl,black +diffmark,black +dvipdfm,black +eGenix,black +etalab-2.0,black +gSOAP-1.3b,black +gnuplot, black +libpng-2.0,black +libselinux-1.0,black +libtiff,black +mpich2,black +psfrag,black +psutils,black +xinetd, black +xpp,black +zlib, white +zlib-acknowledgement,white \ No newline at end of file diff --git a/src/ac/acl/package_license/config/license_translations b/src/ac/acl/package_license/config/license_translations new file mode 100644 index 0000000000000000000000000000000000000000..7472de792d7fc5b5b397fd18d65dc0613e1ec374 --- /dev/null +++ b/src/ac/acl/package_license/config/license_translations @@ -0,0 +1,457 @@ +(MIT), MIT +(mit), MIT +(per1), Artistic-1.0-Perl +2-clause, BSD-2-Clause +3dfx Glide License,Glide +AGPL-3, AGPL-3.0 +AMD's plpa_map.c License,AMDPLPA +ANTLR Software Rights Notice,ANTLR-PD +APL-2.0, Apache-2.0 +APL2, Apache-2.0 +APL2.0, Apache-2.0 +ASL 2.0, Apache-2.0 +ASL-2, Apache-2.0 +ASL-2.0, Apache-2.0 +Abstyles License,Abstyles +Academic Free License v1.1,AFL-1.1 +Academic Free License v1.2,AFL-1.2 +Academic Free License v2.0,AFL-2.0 +Academic Free License v2.1,AFL-2.1 +Academic Free License v3.0,AFL-3.0 +Academy of Motion Picture Arts and Sciences BSD,AMPAS +Adaptive Public License 1.0,APL-1.0 +Adobe Glyph List License,Adobe-Glyph +Adobe Postscript AFM License,APAFML +Adobe Systems Incorporated Source Code License Agreement,Adobe-2006 +Affero General Public License v1.0 only,AGPL-1.0-only +Affero General Public License v1.0 or later,AGPL-1.0-or-later +Afmparse License,Afmparse +Aladdin Free Public License,Aladdin +Amazon Digital Services License,ADSL +Apache, Apache-2.0 +Apache 2.0, Apache-2.0 +Apache License 1.1,Apache-1.1 +Apache License 2.0, Apache-2.0 +Apache License, Version 2.0, Apache-2.0 +Apache-2, Apache-2.0 +Apache2.0, Apache-2.0 +Apachev2, Apache-2.0 +Apple MIT License,AML +Apple Public Source License 1.0,APSL-1.0 +Apple Public Source License 1.1,APSL-1.1 +Apple Public Source License 1.2,APSL-1.2 +Apple Public Source License 2.0,APSL-2.0 +Artistic License, Artistic +Artistic License 1.0,Artistic-1.0 +Artistic License 1.0 (Perl),Artistic-1.0-Perl +Artistic License 1.0 w/clause 8,Artistic-1.0-cl8 +Artistic License 2.0,Artistic-2.0 +Artistic license,artistic +Artistic license 2.0,artistic-2.0 +Artistic-1.0+GPL-1.0, Artistic-1.0 GPL-1.0 +Attribution Assurance License,AAL +BSD, BSD +BSD 1-Clause License,BSD-1-Clause +BSD 2-Clause "Simplified" License,BSD-2-Clause +BSD 3-Clause "New" or "Revised" License,BSD-3-Clause +BSD 3-Clause No Nuclear License,BSD-3-Clause-No-Nuclear-License +BSD 3-Clause No Nuclear License 2014,BSD-3-Clause-No-Nuclear-License-2014 +BSD 3-Clause No Nuclear Warranty,BSD-3-Clause-No-Nuclear-Warranty +BSD 3-Clause Open MPI variant,BSD-3-Clause-Open-MPI +BSD Protection License,BSD-Protection +BSD Source Code Attribution,BSD-Source-Code +BSD Zero Clause License,0BSD +BSD with attribution,BSD-3-Clause-Attribution +BSD(3-clause), BSD-3-Clause +BSD-2-Clause Plus Patent License,BSD-2-Clause-Patent +BSD-4-Clause (University of California-Specific),BSD-4-Clause-UC +BSD_2_clause, BSD-2-Clause +BSD_3_clause, BSD-3-Clause +Bahyph License,Bahyph +Barr License,Barr +Beerware License,Beerware +BitTorrent Open Source License v1.0,BitTorrent-1.0 +Blue Oak Model License 1.0.0,BlueOak-1.0.0 +Boost, BSL-1.0 +Boost Software License 1.0,BSL-1.0 +Borceux license,Borceux +CC0, CC0-1.0 +CERN Open Hardware Licence Version 2 - Permissive,CERN-OHL-P-2.0 +CERN Open Hardware Licence Version 2 - Strongly Reciprocal,CERN-OHL-S-2.0 +CERN Open Hardware Licence Version 2 - Weakly Reciprocal,CERN-OHL-W-2.0 +CERN Open Hardware Licence v1.1,CERN-OHL-1.1 +CERN Open Hardware Licence v1.2,CERN-OHL-1.2 +CMU License,MIT-CMU +CNRI Jython License,CNRI-Jython +CNRI Python License,CNRI-Python +CNRI Python Open Source GPL Compatible License Agreement,CNRI-Python-GPL-Compatible +CPL, CPL-1.0 +CUA Office Public License v1.0,CUA-OPL-1.0 +Caldera License,Caldera +CeCILL Free Software License Agreement v1.0,CECILL-1.0 +CeCILL Free Software License Agreement v1.1,CECILL-1.1 +CeCILL Free Software License Agreement v2.1,CECILL-2.1 +Code Project Open License 1.02,CPOL-1.02 +Common Development and Distribution License 1.0,CDDL-1.0 +Common Development and Distribution License 1.1,CDDL-1.1 +Common Public Attribution License 1.0,CPAL-1.0 +Common Public License 1.0,CPL-1.0 +Commons Clause License v1.0,Commons Clause +Community Data License Agreement Permissive 1.0,CDLA-Permissive-1.0 +Community Data License Agreement Sharing 1.0,CDLA-Sharing-1.0 +Computer Associates Trusted Open Source License 1.1,CATOSL-1.1 +Creative Commons Attribution 1.0 Generic,CC-BY-1.0 +Creative Commons Attribution 2.0 Generic,CC-BY-2.0 +Creative Commons Attribution 2.5 Generic,CC-BY-2.5 +Creative Commons Attribution 3.0 Unported,CC-BY-3.0 +Creative Commons Attribution 4.0 International,CC-BY-4.0 +Creative Commons Attribution No Derivatives 1.0 Generic,CC-BY-ND-1.0 +Creative Commons Attribution No Derivatives 2.0 Generic,CC-BY-ND-2.0 +Creative Commons Attribution No Derivatives 2.5 Generic,CC-BY-ND-2.5 +Creative Commons Attribution No Derivatives 3.0 Unported,CC-BY-ND-3.0 +Creative Commons Attribution No Derivatives 4.0 International,CC-BY-ND-4.0 +Creative Commons Attribution Non Commercial 1.0 Generic,CC-BY-NC-1.0 +Creative Commons Attribution Non Commercial 2.0 Generic,CC-BY-NC-2.0 +Creative Commons Attribution Non Commercial 2.5 Generic,CC-BY-NC-2.5 +Creative Commons Attribution Non Commercial 3.0 Unported,CC-BY-NC-3.0 +Creative Commons Attribution Non Commercial 4.0 International,CC-BY-NC-4.0 +Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic,CC-BY-NC-ND-1.0 +Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic,CC-BY-NC-ND-2.0 +Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic,CC-BY-NC-ND-2.5 +Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported,CC-BY-NC-ND-3.0 +Creative Commons Attribution Non Commercial No Derivatives 4.0 International,CC-BY-NC-ND-4.0 +Creative Commons Attribution Non Commercial Share Alike 1.0 Generic,CC-BY-NC-SA-1.0 +Creative Commons Attribution Non Commercial Share Alike 2.0 Generic,CC-BY-NC-SA-2.0 +Creative Commons Attribution Non Commercial Share Alike 2.5 Generic,CC-BY-NC-SA-2.5 +Creative Commons Attribution Non Commercial Share Alike 3.0 Unported,CC-BY-NC-SA-3.0 +Creative Commons Attribution Non Commercial Share Alike 4.0 International,CC-BY-NC-SA-4.0 +Creative Commons Attribution Share Alike 1.0 Generic,CC-BY-SA-1.0 +Creative Commons Attribution Share Alike 2.0 Generic,CC-BY-SA-2.0 +Creative Commons Attribution Share Alike 2.5 Generic,CC-BY-SA-2.5 +Creative Commons Attribution Share Alike 3.0 Unported,CC-BY-SA-3.0 +Creative Commons Attribution Share Alike 4.0 International,CC-BY-SA-4.0 +Creative Commons Public Domain Dedication and Certification,CC-PDDC +Creative Commons Zero v1.0 Universal,CC0-1.0 +Crossword License,Crossword +Cryptographic Autonomy License 1.0,CAL-1.0 +Cryptographic Autonomy License 1.0 (Combined Work Exception),CAL-1.0-Combined-Work-Exception +CrystalStacker License,CrystalStacker +Cube License,Cube +DMIT License,DMIT +DOC License,DOC +DSDP License,DSDP +Deutsche Freie Software Lizenz,D-FSL-1.0 +Dotseqn License,Dotseqn +EU DataGrid Software License,EUDatagrid +Eclipse Public License, EPL +Eclipse Public License 1.0,EPL-1.0 +Eclipse Public License 2.0,EPL-2.0 +Educational Community License v1.0,ECL-1.0 +Educational Community License v2.0,ECL-2.0 +Eiffel Forum License v1.0,EFL-1.0 +Eiffel Forum License v2.0,EFL-2.0 +Enlightenment License (e16),MIT-advertising +Entessa Public License v1.0,Entessa +Erlang Public License v1.1,ErlPL-1.1 +Etalab Open License 2.0,etalab-2.0 +European Union Public License 1.0,EUPL-1.0 +European Union Public License 1.1,EUPL-1.1 +European Union Public License 1.2,EUPL-1.2 +Eurosym License,Eurosym +Expat, MIT +FSF Unlimited License,FSFUL +FSF Unlimited License (with License Retention),FSFULLR +Fair License,Fair +Frameworx Open License 1.0,Frameworx-1.0 +FreeImage Public License v1.0,FreeImage +GFDL1.1, GFDL-1.1 +GL2PS License,GL2PS +GNU Affero General Public License v3.0 only,AGPL-3.0-only +GNU Affero General Public License v3.0 or later,AGPL-3.0-or-later +GNU GENERAL PUBLIC LICENSE, GPL+ +GNU General Public License v1.0 only,GPL-1.0-only +GNU General Public License v1.0 or later,GPL-1.0-or-later +GNU General Public License v2.0 only,GPL-2.0-only +GNU General Public License v2.0 or later,GPL-2.0-or-later +GNU General Public License v3.0 only,GPL-3.0-only +GNU General Public License v3.0 or later,GPL-3.0-or-later +GNU LESSER GENERAL PUBLIC LICENSE, LGPL-2.1+ +GNU Lesser General Public License v2.1 only,LGPL-2.1-only +GNU Lesser General Public License v2.1 or later,LGPL-2.1-or-later +GNU Lesser General Public License v3.0 only,LGPL-3.0-only +GNU Lesser General Public License v3.0 or later,LGPL-3.0-or-later +GNU Library General Public License v2 only,LGPL-2.0-only +GNU Library General Public License v2 or later,LGPL-2.0-or-later +GPL(==-2), GPL-2.0 +GPL(>=-2), GPL-2.0+ +GPL(>=-2.0), GPL-2.0+ +GPL(>=-2.1), GPL-2.0 +GPL(>=-3), GPL-3.0 +GPL(>=2), GPL-2.0+ +GPL(>=3), GPL-3.0+ +GPL-2, GPL-2.0 +GPL-2+, GPL-2.0+ +GPL-2.0, GPL-2.0 +GPL-2.0+, GPL-2.0+ +GPL-2.0+LGPL-2.1, GPL-2.0 LGPL-2.1 +GPL-2.0-or-later, GPL-2.0+ +GPL-3, GPL-3.0 +GPL-3+, GPL-3.0 +GPL-3.0, GPL-3.0 +GPL-3.0+, GPL-3.0+ +GPL2, GPL-2.0 +GPL3, GPL-3.0 +GPLV2, GPL-2.0 +GPLV3, GPL-3.0 +GPLv2, GPL-2.0 +GPLv2+, GPL-2.0+ +GPLv3, GPL-3.0 +GPLv3+, GPL-3.0+ +Giftware License,Giftware +Glulxe License,Glulxe +Haskell Language Report License,HaskellReport +Hippocratic License 2.1,Hippocratic-2.1 +Historical Permission Notice and Disclaimer,HPND +Historical Permission Notice and Disclaimer - sell variant,HPND-sell-variant +IBM PowerPC Initialization and Boot Software,IBM-pibs +IBM Public License v1.0,IPL-1.0 +ICU License,ICU +IPA Font License,IPA +ISC License,ISC +ISCL , ISC +ImageMagick License,ImageMagick +Independent JPEG Group License,IJG +Info-ZIP License,Info-ZIP +Intel ACPI Software License Agreement,Intel-ACPI +Intel Open Source License,Intel +Interbase Public License v1.0,Interbase-1.0 +JSON License,JSON +Japan Network Information Center License,JPNIC +JasPer License,JasPer-2.0 +LGPL(>=-2), LGPL-2.0+ +LGPL(>=-2.1), LGPL-2.1 +LGPL(>=2), LGPL-2.0+ +LGPL-2, LGPL-2.0 +LGPL-2.0+, LGPL-2.0+ +LGPL-2.1+, LGPL-2.1+ +LGPL-2.1-or-later, LGPL-2.1+ +LGPL-3, LGPL-3.0 +LGPL-3+, LGPL-3.0+ +LGPLv2, LGPL-2.0 +LGPLv2+, LGPL-2.1+ +LGPLv2.1, LGPL-2.1 +LGPLv2.1+, LGPL-2.1+ +LGPLv3, LGPL-3.0 +LGPLv3+, LGPL-3.0+ +LaTeX Project Public License v1.0,LPPL-1.0 +LaTeX Project Public License v1.1,LPPL-1.1 +LaTeX Project Public License v1.3c,LPPL-1.3c +Latex2e License,Latex2e +Lawrence Berkeley National Labs BSD variant license,BSD-3-Clause-LBNL +Leptonica License,Leptonica +Lesser General Public License For Linguistic Resources,LGPLLR +Licence Art Libre 1.2,LAL-1.2 +Licence Art Libre 1.3,LAL-1.3 +Licence Libre du Québec - Permissive version 1.1,LiLiQ-P-1.1 +Licence Libre du Québec - Réciprocité forte version 1.1,LiLiQ-Rplus-1.1 +Licence Libre du Québec - Réciprocité version 1.1,LiLiQ-R-1.1 +Linux Kernel Variant of OpenIB.org license,Linux-OpenIB +Lucent Public License Version 1.0,LPL-1.0 +Lucent Public License v1.02,LPL-1.02 +MIT, MIT +MIT +no-false-attribs license,MITNFA +MIT License, MIT +MIT No Attribution,MIT-0 +MIT/X, MIT +MPL-2, MPL-2.0 +MPL2, MPL-2.0 +MPLv1.1, MPL-1.1 +MPLv2, MPL-2.0 +MPLv2.0, MPL-2.0 +MPLv2.0,, MPL-2.0 +MakeIndex License,MakeIndex +Matrix Template Library License,MTLL +Microsoft Public License,MS-PL +Microsoft Reciprocal License,MS-RL +Motosoto License,Motosoto +Mozilla Public License 1.0,MPL-1.0 +Mozilla Public License 1.1,MPL-1.1 +Mozilla Public License 2.0,MPL-2.0 +Mozilla Public License 2.0 (no copyleft exception),MPL-2.0-no-copyleft-exception +Mulan Permissive Software License v1,MulanPSL-1.0 +Mulan Permissive Software License, Version 1,MulanPSL-1.0 +Mulan Permissive Software License, Version 2,MulanPSL-2.0 +Multics License,Multics +Mup License,Mup +NASA Open Source Agreement 1.3,NASA-1.3 +NRL License,NRL +NTP License,NTP +NTP No Attribution,NTP-0 +Naumen Public License,Naumen +Net Boolean Public License v1,NBPL-1.0 +Net-SNMP License,Net-SNMP +NetCDF license,NetCDF +Nethack General Public License,NGPL +Newsletr License,Newsletr +No Limit Public License,NLPL +Nokia Open Source License,Nokia +Non-Commercial Government Licence,NCGL-UK-2.0 +Non-Profit Open Software License 3.0,NPOSL-3.0 +Norwegian Licence for Open Government Data,NLOD-1.0 +Noweb License,Noweb +OCLC Research Public License 2.0,OCLC-2.0 +ODC Public Domain Dedication & License 1.0,PDDL-1.0 +OFL, OFL +OGC Software License, Version 1.0,OGC-1.0 +OSET Public License version 2.1,OSET-PL-2.1 +Open CASCADE Technology Public License,OCCT-PL +Open Data Commons Attribution License v1.0,ODC-By-1.0 +Open Government Licence - Canada,OGL-Canada-2.0 +Open Government Licence v1.0,OGL-UK-1.0 +Open Government Licence v2.0,OGL-UK-2.0 +Open Government Licence v3.0,OGL-UK-3.0 +Open Group Test Suite License,OGTSL +Open LDAP Public License 2.2.2,OLDAP-2.2.2 +Open LDAP Public License v1.1,OLDAP-1.1 +Open LDAP Public License v1.2,OLDAP-1.2 +Open LDAP Public License v1.3,OLDAP-1.3 +Open LDAP Public License v1.4,OLDAP-1.4 +Open LDAP Public License v2.0 (or possibly 2.0A and 2.0B),OLDAP-2.0 +Open LDAP Public License v2.0.1,OLDAP-2.0.1 +Open LDAP Public License v2.1,OLDAP-2.1 +Open LDAP Public License v2.2,OLDAP-2.2 +Open LDAP Public License v2.2.1,OLDAP-2.2.1 +Open LDAP Public License v2.4,OLDAP-2.4 +Open LDAP Public License v2.5,OLDAP-2.5 +Open LDAP Public License v2.6,OLDAP-2.6 +Open LDAP Public License v2.8,OLDAP-2.8 +Open Market License,OML +Open Public License v1.0,OPL-1.0 +Open Software License 1.0,OSL-1.0 +Open Software License 2.0,OSL-2.0 +Open Software License 2.1,OSL-2.1 +Open Software License 3.0,OSL-3.0 +Open Use of Data Agreement v1.0,O-UDA-1.0 +OpenSSL License,OpenSSL +PHP License v3.0,PHP-3.0 +PNG Reference Library version 2,libpng-2.0 +PSF, Python-2.0 +Perl, Artistic-1.0-Perl +Plexus Classworlds License,Plexus +PolyForm Noncommercial License 1.0.0,PolyForm-Noncommercial-1.0.0 +PolyForm Small Business License 1.0.0,PolyForm-Small-Business-1.0.0 +PostgreSQL License,PostgreSQL +Python, Python-2.0 +Python License 2.0,Python-2.0 +Python Software Foundation License 2.0,PSF-2.0 +Q Public License 1.0,QPL-1.0 +Qhull License,Qhull +RSA Message-Digest License,RSA-MD +Rdisc License,Rdisc +RealNetworks Public Source License v1.0,RPSL-1.0 +Reciprocal Public License 1.1,RPL-1.1 +Reciprocal Public License 1.5,RPL-1.5 +Red Hat eCos Public License v1.1,RHeCos-1.1 +Ricoh Source Code Public License,RSCPL +Ruby License,Ruby +SCEA Shared Source License,SCEA +SGI Free Software License B v1.0,SGI-B-1.0 +SGI Free Software License B v1.1,SGI-B-1.1 +SIL Open Font License 1.0 with Reserved Font Name,OFL-1.0-RFN +SIL Open Font License 1.0 with no Reserved Font Name,OFL-1.0-no-RFN +SIL Open Font License 1.1,OFL-1.1 +SIL Open Font License 1.1 with Reserved Font Name,OFL-1.1-RFN +SIL Open Font License 1.1 with no Reserved Font Name,OFL-1.1-no-RFN +SNIA Public License 1.1,SNIA +SQLite Blessing,blessing +SSH OpenSSH license,SSH-OpenSSH +SSH short notice,SSH-short +Sax Public Domain Notice,SAX-PD +Saxpath License,Saxpath +Scheme Widget Library (SWL) Software License Agreement,SWL +Secure Messaging Protocol Public License,SMPPL +Sendmail License,Sendmail +Sendmail License 8.23,Sendmail-8.23 +Server Side Public License, v 1,SSPL-1.0 +Simple Public License 2.0,SimPL-2.0 +Sleepycat License,Sleepycat +Solderpad Hardware License v0.5,SHL-0.5 +Solderpad Hardware License, Version 0.51,SHL-0.51 +Spencer License 86,Spencer-86 +Spencer License 94,Spencer-94 +Spencer License 99,Spencer-99 +SugarCRM Public License v1.1.3,SugarCRM-1.1.3 +Sun Industry Standards Source License v1.1,SISSL +Sun Industry Standards Source License v1.2,SISSL-1.2 +Sun Public License v1.0,SPL-1.0 +Sybase Open Watcom Public License 1.0,Watcom-1.0 +TAPR Open Hardware License v1.0,TAPR-OHL-1.0 +TCL/TK License,TCL +TCP Wrappers License,TCP-wrappers +TMate Open Source License,TMate +TORQUE v2.5+ Software License v1.1,TORQUE-1.1 +Technische Universitaet Berlin License 1.0,TU-Berlin-1.0 +Technische Universitaet Berlin License 2.0,TU-Berlin-2.0 +The MirOS Licence,MirOS +The Parity Public License 6.0.0,Parity-6.0.0 +The Parity Public License 7.0.0,Parity-7.0.0 +The Unicode Character Database,UCD +Trusster Open Source License,TOSL +Unicode License Agreement - Data Files and Software (2015),Unicode-DFS-2015 +Unicode License Agreement - Data Files and Software (2016),Unicode-DFS-2016 +Unicode Terms of Use,Unicode-TOU +Universal Permissive License v1.0,UPL-1.0 +University of Illinois/NCSA Open Source License,NCSA +Upstream Compatibility License v1.0,UCL-1.0 +VIM, Vim +VOSTROM Public License for Open Source,VOSTROM +Vovida Software License v1.0,VSL-1.0 +W3C Software Notice and Document License (2015-05-13),W3C-20150513 +W3C Software Notice and License (1998-07-20),W3C-19980720 +W3C Software Notice and License (2002-12-31),W3C +Wsuipa License,Wsuipa +X.Net License,Xnet +XPP License,xpp +XSkat License,XSkat +Xerox License,Xerox +Yahoo! Public License v1.0,YPL-1.0 +ZLIB, Zlib +ZPL, ZPL-2.0 +ZPL 2.1, ZPL-2.1 +Zed License,Zed +Zimbra Public License v1.4,Zimbra-1.4 +Zope Public License 1.1,ZPL-1.1 +Zope Public License 2.0,ZPL-2.0 +Zope Public License 2.1,ZPL-2.1 +apache, Apache-2.0 +artistic2, Artistic-2.0 +artistic_2, Artistic-2.0 +bzip2 and libbzip2 License v1.0.5,bzip2-1.0.5 +bzip2 and libbzip2 License v1.0.6,bzip2-1.0.6 +copyleft-next 0.3.0,copyleft-next-0.3.0 +copyleft-next 0.3.1,copyleft-next-0.3.1 +curl License,curl +diffmark license,diffmark +dvipdfm License,dvipdfm +eGenix.com Public License 1.1.0,eGenix +enna License,MIT-enna +feh License,MIT-feh +gSOAP Public License v1.3b,gSOAP-1.3b +gplv3, GPL-3.0 +http://creativecommons.org/licenses/BSD/, BSD-2-Clause +http://opensource.org/licenses/MIT, MIT +http://www.apache.org/licenses/LICENSE-2.0, Apache-2.0 +lgpl, LGPL-2.1 +libpng License,Libpng +libselinux public domain notice,libselinux-1.0 +libtiff License,libtiff +mpich2 License,mpich2 +perl, Artistic-1.0-Perl +psfrag License,psfrag +psutils License,psutils +version 3 of the GNU General Public License, GPL-3.0+ +w3c, W3C +zlib, Zlib +zlib License,Zlib +zlib/libpng, zlib-acknowledgement +zlib/libpng License with Acknowledgement,zlib-acknowledgement diff --git a/src/ac/acl/package_license/package_license.py b/src/ac/acl/package_license/package_license.py new file mode 100644 index 0000000000000000000000000000000000000000..cfac975f9b6fdacab8cf0c8170401d9c699aaf7b --- /dev/null +++ b/src/ac/acl/package_license/package_license.py @@ -0,0 +1,193 @@ +# -*- encoding=utf-8 -*- +""" +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-10-16 +# Description: check spec file +# ********************************************************************************** +""" + +import logging +import os +import re +import chardet + +from src.ac.common.pyrpm import Spec, replace_macros +from src.ac.common.rpm_spec_adapter import RPMSpecAdapter + +logger = logging.getLogger("ac") + +class PkgLicense(object): + """ + 解析获取软件包中源码、spec中的license + 进行白名单校验、一致性检查 + """ + + LICENSE_FILE_TARGET = ["apache-2.0", + "artistic", + "artistic.txt", + "libcurllicense", + "gpl.txt", + "gpl2.txt", + "gplv2.txt", + "notice", + "about_bsd.txt", + "mit", + "pom.xml", + "meta.yml"] + + LICENSE_TARGET_PAT = re.compile(r"^(copying)|(copyright)|(copyrights)|(licenses)|(licen[cs]e)(\.(txt|xml))?$") + + WHITE_LIST_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), + "config", + "license_list") + LICENSE_TRANS_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), + "config", + "license_translations") + + def __init__(self): + self._white_black_list = {} + self._license_translation = {} + + def _load_license_dict(self, filename): + """ + read the dict from license file + """ + result = {} + if not os.path.isfile(filename): + logger.warning("not found the config file: %s", os.path.basename(filename)) + return result + with open(filename, "r") as f: + for line in f: + if line.startswith("#"): + continue + k, v = line.rsplit(",", 1) + k = PkgLicense._auto_decode_str(k.strip()) + v = PkgLicense._auto_decode_str(v.strip()) + result[k] = v + return result + + def load_config(self): + """ + Load the license white list and translation list into dict + """ + self._white_black_list = self._load_license_dict(self.WHITE_LIST_PATH) + self._license_translation = self._load_license_dict(self.LICENSE_TRANS_PATH) + + def check_license_safe(self, licenses): + """ + Check if the license is in the blacklist + """ + result = True + for lic in licenses: + res = self._white_black_list.get(lic, "Need review") + if res == "white": + logger.info("This license: %s is safe", lic) + elif res == "black": + logger.error("This license: %s is not safe", lic) + result = False + else: + logger.warning("This license: %s need to be review", lic) + result = False + return result + + def translate_license(self, licenses): + """ + Convert license to uniform format + """ + result = set() + for lic in licenses: + real_license = self._license_translation.get(lic, lic) + result.add(real_license) + return result + + @staticmethod + def split_license(licenses): + """ + 分割spec license字段的license + """ + license_set = re.split(r'/\s?|\(|\)|\,|[Aa][Nn][Dd]|or|OR|\s?/g', licenses) + for index in range(len(license_set)): # 去除字符串首尾空格 + license_set[index] = license_set[index].strip() + return set(filter(None, license_set)) # 去除list中空字符串 + + # 以下为从license文件中获取license + def scan_licenses_in_license(self, srcdir): + """ + Find LICENSE files and scan. + """ + licenses_in_file = set() + if not os.path.exists(srcdir): + logger.error("%s not exist.", srcdir) + return licenses_in_file + + for root, dirnames, filenames in os.walk(srcdir): + for filename in filenames: + if (filename.lower() in self.LICENSE_FILE_TARGET + or self.LICENSE_TARGET_PAT.search(filename.lower())): + logger.info("scan the license target file: %s", filename) + licenses_in_file.update( + self.scan_licenses( + os.path.join(root, filename))) + logger.info("all licenses from src: %s", ", ".join([data.encode("utf-8") for data in licenses_in_file])) + return licenses_in_file + + def scan_licenses(self, copying): + """ + Scan licenses from copying file and add to licenses_for_source_files. + if get contents failed or decode data failed, return nothing. + """ + licenses_in_file = set() + + if not os.path.exists(copying): + logger.warning("file: %s not exist", copying) + return licenses_in_file + + for word in self._license_translation: + if word in copying: + licenses_in_file.add(word) + + with open(copying, "rb") as f: + data = f.read() + data = PkgLicense._auto_decode_str(data) + if not data: + return licenses_in_file + for word in self._license_translation: + try: + if word in data: + licenses_in_file.add(word) + except UnicodeDecodeError as e: + logger.exception("decode error: %s", str(e)) + return licenses_in_file + + @staticmethod + def _decode_str(data, charset): + """ + Decode the license string. return the license string or nothing. + """ + if not charset: + return "" + return data.decode(charset) + + @staticmethod + def _auto_decode_str(data): + return PkgLicense._decode_str(data, chardet.detect(data)["encoding"]) + + @staticmethod + def check_licenses_is_same(licenses_for_spec, licenses_for_source_files): + """ + Check if the licenses from SPEC is the same as the licenses from LICENSE file. + if same, return True. if not same return False. + """ + if not licenses_for_source_files: + return False + return licenses_for_spec.issuperset(licenses_for_source_files) \ No newline at end of file diff --git a/src/ac/acl/package_yaml/__init__.py b/src/ac/acl/package_yaml/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..054319cd51014650ac251515823879e185c4d0de --- /dev/null +++ b/src/ac/acl/package_yaml/__init__.py @@ -0,0 +1,17 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-17 +# Description: +# ***********************************************************************************/ +""" \ No newline at end of file diff --git a/src/ac/acl/package_yaml/check_repo.py b/src/ac/acl/package_yaml/check_repo.py new file mode 100644 index 0000000000000000000000000000000000000000..9541ea3923d2086cb0aa8bf868545481a2ac9c5a --- /dev/null +++ b/src/ac/acl/package_yaml/check_repo.py @@ -0,0 +1,540 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-22 +# Description: check yaml file in software package +# ***********************************************************************************/ +""" +# \ / /| /| /| / +# \ / /_| / | / | / +# / / | / | / | / +# / / | / |/ | /_____ + +import logging +import re +import urlparse +import requests +import json +import subprocess +import tldextract +import abc + +logging.getLogger("ac") + + +class AbsReleaseTags(object): + """ + 获取release tags的抽象类 + """ + + __metaclass__ = abc.ABCMeta + def __init__(self, version_control): + self.version_control = version_control + + @abc.abstractmethod + def url(self, repo): + """ + 抽象方法 + """ + pass + + @abc.abstractmethod + def get_tags(self, repo): + """ + 抽象方法 + """ + pass + + +class DefaultReleaseTags(AbsReleaseTags): + """ + 获取release tags的基类 + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return "" + + def get_tags(self, repo): + """ + 通过url获取上游社区的release tags + return: list + """ + logging.info("unsupported version control: {}".format(self.version_control)) + return [] + + +class HttpReleaseTagsMixin(object): + """ + 通过web请求形式获取release tags + """ + DEFAULT_REQ_HEADER = { + 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64)' + } + + def get_redirect_resp(self, url, response): + """ + 获取重定向的url和cookie + return: bool, str, list + """ + cookie = set() + href = "" + need_redirect = False + for line in response.text.splitlines(): + line = line.strip() + if line.startswith("Redirecting"): + logging.debug("Redirecting with document.cookie") + need_redirect = True + search_result = re.search(r"document\.cookie=\"(.*)\";", line) + if search_result: + cookie = cookie | set(search_result.group(1).split(';')) + search_result = re.search(r"document\.location\.href=\"(.*)\";", line) + if search_result: + href = search_result.group(1) + new_url = urlparse.urljoin(url, href) + if "" in cookie: + cookie.remove("") + return need_redirect, new_url, list(cookie) + + def get_request_response(self, url, timeout=30, headers=None): + """ + 获取url请求获取response + return: reponse + """ + headers = self.DEFAULT_REQ_HEADER if headers is None else headers + try: + response = requests.get(url, headers=headers, timeout=timeout) + need_redirect, new_url, cookies = self.get_redirect_resp(url, response) + if tldextract.extract(url).domain != tldextract.extract(new_url).domain: # 判断域名是否一致 预防csrf攻击 + logging.warning("domain of redirection link is different: {}".format(new_url)) + return "" + if need_redirect: + cookie_dict = {} + for cookie in cookies: + key, val = cookie.split("=") + cookie_dict[key] = val + url = new_url + response = requests.get(url, headers=headers, cookies=cookie_dict, timeout=timeout) + except requests.exceptions.SSLError as e: + logging.warning("requests {} ssl exception, {}".format(url, e)) + return "" + except requests.exceptions.Timeout as e: + logging.warning("requests timeout") + return "" + except requests.exceptions.RequestException as e: + logging.warning("requests exception, {}".format(e)) + return "" + return response + + +class HgReleaseTags(AbsReleaseTags, HttpReleaseTagsMixin): + """ + 获取hg上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin(repo + "/", "json-tags") if repo else "" + + def get_tags(self, repo): + """ + 通过url获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get {vc} tags".format(repo=url, vc=self.version_control)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_request_response(url) + if not response: + logging.warning("unable to get response:") + return [] + try: + tags_json = json.loads(response.text) + temp_tags = tags_json.get("tags") + temp_tags.sort(reverse=True, key=lambda x: x["date"][0]) + release_tags = [tag["tag"] for tag in temp_tags] + except Exception as e: + logging.error("exception, {}".format(e)) + return [] + return release_tags + + +class HgRawReleaseTags(AbsReleaseTags, HttpReleaseTagsMixin): + """ + 获取hg raw上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin(repo + "/", "raw-tags") if repo else "" + + def get_tags(self, repo): + """ + 通过url获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get {vc} tags".format(repo=url, vc=self.version_control)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_request_response(url) + release_tags = [] + for line in response.text.splitlines(): + release_tags.append(line.split()[0]) + return release_tags + + +class MetacpanReleaseTags(AbsReleaseTags, HttpReleaseTagsMixin): + """ + 获取metacpan上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin("https://metacpan.org/release/", repo) if repo else "" + + def get_tags(self, repo): + """ + 通过url获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get {vc} tags".format(repo=url, vc=self.version_control)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_request_response(url) + resp_lines = response.text.splitlines() + release_tags = [] + tag_condition = "value=\"/release" + for index in range(len(resp_lines) - 1): + if tag_condition in resp_lines[index]: + tag = resp_lines[index + 1] + index += 1 + if "DEV" in tag: + continue + tag = tag.strip() + release_tags.append(tag) + return release_tags + + +class PypiReleaseTags(AbsReleaseTags, HttpReleaseTagsMixin): + """ + 获取pypi上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin("https://pypi.org/pypi/", repo + "/json") if repo else "" + + def get_tags(self, repo): + """ + 通过url获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get {vc} tags".format(repo=url, vc=self.version_control)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_request_response(url) + try: + tags_json = response.json() + release_tags = [tag for tag in tags_json.get("releases")] + except Exception as e: + logging.error("exception, {}".format(e)) + return [] + return release_tags + + +class RubygemReleaseTags(AbsReleaseTags, HttpReleaseTagsMixin): + """ + 获取rubygem上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin("https://rubygems.org/api/v1/versions/", repo + ".json") if repo else "" + + def get_tags(self, repo): + """ + 通过url获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get {vc} tags".format(repo=url, vc=self.version_control)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_request_response(url) + try: + tags_json = response.json() + release_tags = [] + for element in tags_json: + if element.get("number"): + release_tags.append(element.get("number")) + except Exception as e: + logging.error("exception, {}".format(e)) + return [] + return release_tags + + +class GnuftpReleaseTags(AbsReleaseTags, HttpReleaseTagsMixin): + """ + 获取gnu-ftp上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin("https://ftp.gnu.org/gnu/", repo) if repo else "" + + def get_tags(self, repo): + """ + 通过url获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get {vc} tags".format(repo=url, vc=self.version_control)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_request_response(url) + pattern = re.compile("href=\"(.*)\">(.*)") + release_tags = [] + for line in response.text.splitlines(): + search_result = pattern.search(line) + if search_result: + release_tags.append(search_result.group(1)) # python2用法 python3不同 + return release_tags + + +class FtpReleaseTags(AbsReleaseTags, HttpReleaseTagsMixin): + """ + 获取ftp上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin('ftp', repo + "/") if repo else "" + + def get_tags(self, repo): + """ + 通过url获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get {vc} tags".format(repo=url, vc=self.version_control)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_request_response(url) + pattern = re.compile("href=\"(.*)\">(.*)") + release_tags = [] + for line in response.text.splitlines(): + search_result = pattern.search(line) + if search_result: + release_tags.append(search_result.group(1)) # python2用法 python3不同 + return release_tags + + +class CmdReleaseTagsMixin(object): + """ + 通过shell命令获取上游社区的release tags + """ + def get_cmd_response(self, cmd_list): + """ + 获取shell命令的reponse + return: reponse + """ + sub_proc = subprocess.Popen(cmd_list, stdout=subprocess.PIPE) + response = sub_proc.stdout.read().decode("utf-8") + if sub_proc.wait(): + logging.warning("{cmd} > encount errors".format(cmd=" ".join(cmd_list))) + return response + + +class SvnReleaseTags(AbsReleaseTags, CmdReleaseTagsMixin): + """ + 通过shell svn命令获取上游社区的release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin(repo + "/", "tags") if repo else "" + + def get_response(self, url): + """ + 生成svn命令并获取reponse + return: response + """ + cmd_list = ["/usr/bin/svn", "ls", "-v", url] + return self.get_cmd_response(cmd_list) + + def get_tags(self, repo): + """ + 通过shell cmd访问远端获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get svn tags".format(repo=url)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_response(url) + release_tags = [] + for line in response.splitlines(): + for item in line.split(): + if item and item[-1] == "/": + release_tags.append(item[:-1]) + break + return release_tags + + +class GitReleaseTags(AbsReleaseTags, CmdReleaseTagsMixin): + """ + 通过shell git命令获取上游社区的release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return repo + + def get_response(self, url): + """ + 生成git命令并获取reponse + return: response + """ + cmd_list = ["git", "ls-remote", "--tags", url] + return self.get_cmd_response(cmd_list) + + def trans_reponse_tags(self, reponse): + """ + 解析git命令返回值为纯数字形式的tag + return: list + """ + release_tags = [] + pattern = re.compile(r"^([^ \t]*)[ \t]*refs\/tags\/([^ \t]*)") + for line in reponse.splitlines(): + match_result = pattern.match(line) + if match_result: + tag = match_result.group(2) + if not tag.endswith("^{}"): + release_tags.append(tag) + return release_tags + + def get_tags(self, repo): + """ + 通过shell cmd访问远端获取上游社区的release tags + return: list + """ + url = self.url(repo) + logging.debug("{repo} : get {vc} tags".format(repo=url, vc=self.version_control)) + if not url: + logging.warning("illegal url: \"\"") + return [] + response = self.get_response(url) + return self.trans_reponse_tags(response) + + +class GithubReleaseTags(GitReleaseTags): + """ + 获取github上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin("https://github.com/", repo + ".git") if repo else "" + + +class GiteeReleaseTags(GitReleaseTags): + """ + 获取gitee上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + return urlparse.urljoin("https://gitee.com/", repo) if repo else "" + + +class GitlabReleaseTags(GitReleaseTags): + """ + 获取gitlab.gnome上游社区release tags + """ + def url(self, repo): + """ + 通过src_repo生成url + return: str + """ + if not repo: + return "" + src_repos = repo.split("/") + if len(src_repos) == 1: + return urlparse.urljoin("https://gitlab.gnome.org/GNOME/", repo + ".git") + else: + return urlparse.urljoin("https://gitlab.gnome.org/", repo + ".git") + + +class ReleaseTagsFactory(object): + """ + ReleaseTags及其子类的工厂类 + """ + VERSION_CTRL_GETTER_MAPPING = { + "hg": HgReleaseTags, + "hg-raw": HgRawReleaseTags, + "github": GithubReleaseTags, + "git": GitReleaseTags, + "gitlab.gnome": GitlabReleaseTags, + "svn": SvnReleaseTags, + "metacpan": MetacpanReleaseTags, + "pypi": PypiReleaseTags, + "rubygem": RubygemReleaseTags, + "gitee": GiteeReleaseTags, + "gnu-ftp": GnuftpReleaseTags, + "ftp": FtpReleaseTags + } + + @staticmethod + def get_release_tags(version_control): + """ + 通过version control返回对应的ReleaseTags的子类 + return: class + """ + release_tags = ReleaseTagsFactory.VERSION_CTRL_GETTER_MAPPING.get(version_control, DefaultReleaseTags) + return release_tags(version_control) \ No newline at end of file diff --git a/src/ac/acl/package_yaml/check_yaml.py b/src/ac/acl/package_yaml/check_yaml.py new file mode 100644 index 0000000000000000000000000000000000000000..62f5d0b01d244514b43d9090ec9ad93d40c4a3d9 --- /dev/null +++ b/src/ac/acl/package_yaml/check_yaml.py @@ -0,0 +1,209 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-17 +# Description: check yaml file in software package +# ***********************************************************************************/ +""" + +import logging +import os +import yaml + +from src.proxy.git_proxy import GitProxy +from src.proxy.requests_proxy import do_requests +from src.ac.framework.ac_base import BaseCheck +from src.ac.framework.ac_result import FAILED, WARNING, SUCCESS +from src.ac.common.gitee_repo import GiteeRepo +from src.ac.acl.package_yaml.check_repo import ReleaseTagsFactory +from src.ac.common.rpm_spec_adapter import RPMSpecAdapter + +logger = logging.getLogger("ac") + +class CheckPackageYaml(BaseCheck): + """ + check yaml file + """ + + NOT_FOUND = "NA" + PACKAGE_YAML_NEEDED_KEY = [ + "version_control", + "src_repo", + "tag_prefix", + "separator"] + + VERSION_CTRL_TRANS = { + "gitlab.gnome": "gnome", + "pypi": "pythonhosted" + } + + def __init__(self, workspace, repo, conf): + super(CheckPackageYaml, self).__init__(workspace, repo, conf) + + self._gp = GitProxy(self._work_dir) + self._gr = GiteeRepo(self._repo, self._work_dir, None) # don't care about decompress + if self._gr.spec_file: + self._spec = RPMSpecAdapter(os.path.join(self._work_dir, self._gr.spec_file)) + else: + self._spec = None + self._yaml_content = None + self._yaml_changed = True + self._is_standard = True + + def is_change_package_yaml(self, base="HEAD~1", head="HEAD~0"): + """ + 如果本次提交变更了yaml,则对yaml进行检查 + :param: + base:作为对比的提交点 + head:此次提交点 + :return: boolean + """ + diff_files = self._gp.diff_files_between_commits(base, head) + package_yaml = "{}.yaml".format(self._repo) # package yaml file name + + for change_file in diff_files: + if change_file == package_yaml: + logger.debug("diff files: {}".format(diff_files)) + return True + return False + + def check_fields(self): + """ + 检查yaml规定字段的完整性 + :return: + """ + if not self._yaml_changed: + return SUCCESS + yaml_path = self._gr.yaml_file + if yaml_path is None: + self._is_standard = False + logger.warning("yaml file missing") + return WARNING + try: + with open(os.path.join(self._work_dir, yaml_path), 'r') as yaml_data: # load yaml data + self._yaml_content = yaml.safe_load(yaml_data) + except IOError as e: + logging.warning("package yaml not exist. {}".format(str(e))) + return WARNING + except yaml.YAMLError as exc: + logging.warning("Error parsering YAML: {}".format(str(exc))) + return WARNING + + result = SUCCESS + for keyword in self.PACKAGE_YAML_NEEDED_KEY: + if keyword not in self._yaml_content: + logger.error("yaml field {} missing".format(keyword)) + self._is_standard = True + result = WARNING + return result + + def check_repo(self): + """ + 检查yaml的有效性,能否从上游社区获取版本信息 + :return: + """ + if not self._yaml_changed: + return SUCCESS + if not self._is_standard: + logger.warning("yaml does not comply with the rule") + return SUCCESS + # get value by key from yaml data + vc = self._yaml_content[self.PACKAGE_YAML_NEEDED_KEY[0]] # value of version_control + sr = self._yaml_content[self.PACKAGE_YAML_NEEDED_KEY[1]] # value of src_repo + + if vc == self.NOT_FOUND or sr == self.NOT_FOUND: + logger.warning("no info for upsteam") + return WARNING + + release_tags = ReleaseTagsFactory.get_release_tags(vc) + tags = release_tags.get_tags(sr) + + if not tags: + logger.warning("failed to get version by yaml, version_control: {t1}, src_repo: {t2}".format(t1=vc, t2=sr)) + return WARNING + return SUCCESS + + def check_repo_domain(self): + """ + 检查spec中source0域名是否包含yaml的version_control,仅做日志告警只返回SUCCESS(autoconf为特例) + :return: + """ + if not self._yaml_changed: + return SUCCESS + if not self._is_standard: + logger.warning("yaml does not comply with the rule") + return SUCCESS + if not self._spec: + logger.warning("spec does not exist") + return SUCCESS + + vc = self._yaml_content[self.PACKAGE_YAML_NEEDED_KEY[0]] + if vc == self.NOT_FOUND: + return SUCCESS + src_url = self._spec.get_source("Source0") + if not src_url: + src_url = self._spec.get_source("Source") + vc = self.VERSION_CTRL_TRANS.get(vc, vc) # 对特殊的版本控制对应的域名进行转换 + logger.debug("version control: {vctrl} source url: {url}".format(vctrl=vc, url=src_url)) + if vc not in src_url: # 通过判断版本控制字段是否在主页url中 判断一致性 + logger.warning("{vc} is not in url: {url}".format(vc=vc, url=src_url)) + return WARNING + return SUCCESS + + def check_repo_name(self): + """ + 检查spec中是否包含yaml中src_repo字段的软件名,仅做日志告警只返回SUCCESS + :return: + """ + if not self._yaml_changed: + return SUCCESS + if not self._is_standard: + logger.warning("yaml does not comply with the rule") + return SUCCESS + if not self._spec: + logger.warning("spec does not exist") + return SUCCESS + + sr = self._yaml_content[self.PACKAGE_YAML_NEEDED_KEY[1]] + if sr == self.NOT_FOUND: + return SUCCESS + + software_name_list = list(filter(None, sr.split("/"))) + + def guess_real_pkgname(name_list): + """ + 解析yaml中src_repo字段对应的软件包名 + :return: + """ + pkgname = name_list[-1] + if len(name_list) > 1 and name_list[-1] == "svn": + pkgname = name_list[-2] + if pkgname.endswith(".git"): + pkgname = os.path.splitext(pkgname)[0] + return pkgname + + software_name = guess_real_pkgname(software_name_list) + src_url = self._spec.get_source("Source0") + if not src_url: + src_url = self._spec.get_source("Source") + logger.debug("software name: {name} source url: {url}".format(name=software_name, url=src_url)) + if software_name not in src_url: + logger.warning("{name} is not in source0: {url}".format(name=software_name, url=src_url)) + return WARNING + return SUCCESS + + def __call__(self, *args, **kwargs): + logger.info("check {} yaml ...".format(self._repo)) + self._yaml_changed = self.is_change_package_yaml() # yaml文件变更 进行检查 + return self.start_check_with_order("fields", "repo_domain", "repo_name", "repo") + diff --git a/src/ac/acl/spec/check_spec.py b/src/ac/acl/spec/check_spec.py index 468b616eb8a30da5be37207de1985279974421ff..6502e91481a280afcc6158b4cad149a9b4d9d786 100644 --- a/src/ac/acl/spec/check_spec.py +++ b/src/ac/acl/spec/check_spec.py @@ -79,7 +79,7 @@ class CheckSpec(BaseCheck): logger.debug("only change package yaml") return SUCCESS - self._gp.checkout_to_commit("HEAD~1") + self._gp.checkout_to_commit_force("HEAD~1") try: gr = GiteeRepo(self._repo, self._work_dir, None) # don't care about decompress fp = self._gp.get_content_of_file_with_commit(gr.spec_file) @@ -88,7 +88,7 @@ class CheckSpec(BaseCheck): return SUCCESS spec_o = RPMSpecAdapter(fp) finally: - self._gp.checkout_to_commit(self._latest_commit) # recover whatever + self._gp.checkout_to_commit_force(self._latest_commit) # recover whatever self._ex_pkgship(spec_o) diff --git a/src/ac/common/gitee_repo.py b/src/ac/common/gitee_repo.py index 696316caa5f447ef9b3f8b7c81ac142e4821f541..3432d4f579c83e9305b5f8eead33b17c835d510e 100644 --- a/src/ac/common/gitee_repo.py +++ b/src/ac/common/gitee_repo.py @@ -1,5 +1,6 @@ # -*- encoding=utf-8 -*- -# ********************************************************************************** +""" +# *********************************************************************************** # Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. # [openeuler-jenkins] is licensed under the Mulan PSL v1. # You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -12,13 +13,15 @@ # Author: # Create: 2020-09-23 # Description: Gitee api proxy -# ********************************************************************************** +# ***********************************************************************************/ +""" import os import logging from src.proxy.git_proxy import GitProxy from src.utils.shell_cmd import shell_cmd_live +from src.ac.acl.package_license.package_license import PkgLicense logger = logging.getLogger("ac") @@ -36,6 +39,7 @@ class GiteeRepo(object): self._compress_files = [] self.spec_file = None + self.yaml_file = None self.patch_dir_mapping = {} self.find_file_path() @@ -57,6 +61,9 @@ class GiteeRepo(object): elif self.is_spec_file(filename): logger.debug("find spec file: {}".format(rel_file_path)) spec_files.append(filename) + elif self.is_package_yaml_file(filename): + logger.debug("find yaml file: {}".format(rel_file_path)) + self.yaml_file = rel_file_path def guess_real_spec_file(): """ @@ -162,40 +169,105 @@ class GiteeRepo(object): return 0 if all(rs) else (1 if any(rs) else -1) + def scan_license_in_spec(self, spec): + """ + Find spec file and scan. If no spec file or open file failed, the program will exit with an error. + """ + if not spec: + return set() + licenses = spec.license + licenses_in_spec = PkgLicense.split_license(licenses) + logger.info("all licenses from SPEC: %s", ", ".join(list(licenses_in_spec))) + return licenses_in_spec + @staticmethod def is_py_file(filename): + """ + 功能描述:判断文件是否是python文件 + 参数:文件名 + 返回值:bool + """ return filename.endswith((".py",)) @staticmethod def is_go_file(filename): + """ + 功能描述:判断文件名是否是go文件 + 参数:文件名 + 返回值:bool + """ return filename.endswith((".go",)) @staticmethod def is_c_cplusplus_file(filename): + """ + 功能描述:判断文件名是否是c++文件 + 参数:文件名 + 返回值:bool + """ return filename.endswith((".c", ".cpp", ".cc", ".cxx", ".c++", ".h", ".hpp", "hxx")) @staticmethod def is_code_file(filename): + """ + 功能描述:判断文件名是否是源码文件 + 参数:文件名 + 返回值:bool + """ return GiteeRepo.is_py_file(filename) \ or GiteeRepo.is_go_file(filename) \ or GiteeRepo.is_c_cplusplus_file(filename) @staticmethod def is_patch_file(filename): + """ + 功能描述:判断文件名是否是补丁文件 + 参数:文件名 + 返回值:bool + """ return filename.endswith((".patch", ".diff")) @staticmethod def is_compress_file(filename): + """ + 功能描述:判断文件名是否是压缩文件 + 参数:文件名 + 返回值:bool + """ return GiteeRepo._is_compress_tar_file(filename) or GiteeRepo._is_compress_zip_file(filename) @staticmethod def _is_compress_zip_file(filename): + """ + 功能描述:判断文件名是否是zip压缩文件 + 参数:文件名 + 返回值:bool + """ return filename.endswith((".zip",)) @staticmethod def _is_compress_tar_file(filename): + """ + 功能描述:判断文件名是否是tar压缩文件 + 参数:文件名 + 返回值:bool + """ return filename.endswith((".tar.gz", ".tar.bz", ".tar.bz2", ".tar.xz", "tgz")) @staticmethod def is_spec_file(filename): + """ + 功能描述:判断文件名是否以.spec结尾 + 参数:文件名 + 返回值:bool + """ return filename.endswith((".spec",)) + + @staticmethod + def is_package_yaml_file(filename): + """ + 功能描述:判断文件名是否以.yaml结尾 + 参数:文件名 + 返回值:bool + """ + return filename.endswith((".yaml",)) diff --git a/src/ac/common/rpm_spec_adapter.py b/src/ac/common/rpm_spec_adapter.py index 65db3aa241d64c8289463bc475a249fbe94e92f1..023f52f46c96346d8393fc994f3266383d7e63db 100644 --- a/src/ac/common/rpm_spec_adapter.py +++ b/src/ac/common/rpm_spec_adapter.py @@ -45,9 +45,24 @@ class RPMSpecAdapter(object): value = getattr(self._adapter, item) if isinstance(value, list): return [replace_macros(item, self._adapter) for item in value] - return replace_macros(value, self._adapter) if value else "" + def get_source(self, key): + """ + get source url from spec.source_dict by key + :return: + """ + src_url = self._adapter.sources_dict.get(key, "") + return replace_macros(src_url, self._adapter) if src_url else "" + + def get_patch(self, key): + """ + get source url from spec.source_dict by key + :return: + """ + patch = self._adapter.patches_dict.get(key, "") + return replace_macros(patch, self._adapter) if patch else "" + def include_x86_arch(self): """ check include x86-64 diff --git a/src/ac/framework/ac.py b/src/ac/framework/ac.py index f2febf6cf2ff499af96e27bbf91be9e2921c32b9..a65efc8e6c959ac406a36e1c40e262aa3e52b609 100644 --- a/src/ac/framework/ac.py +++ b/src/ac/framework/ac.py @@ -22,6 +22,7 @@ import logging import json import argparse import importlib +import datetime from yaml.error import YAMLError @@ -30,18 +31,24 @@ class AC(object): """ ac entrypoint """ - def __init__(self, conf): + def __init__(self, conf, community="src-openeuler"): + """ + + :param conf: 配置文件路径 + :param community: src-openeuler or openeuler + :return: + """ self._ac_check_elements = {} # 门禁项 self._ac_check_result = [] # 门禁结果结果 acl_path = os.path.realpath(os.path.join(os.path.dirname(__file__), "../acl")) self._acl_package = "src.ac.acl" # take attention about import module self.load_check_elements_from_acl_directory(acl_path) - self.load_check_elements_from_conf(conf) + self.load_check_elements_from_conf(conf, community) logger.debug("check list: {}".format(self._ac_check_elements)) - def check_all(self, workspace, repo, **kwargs): + def check_all(self, workspace, repo, dataset, **kwargs): """ 门禁检查 :param workspace: @@ -95,7 +102,9 @@ class AC(object): if not hint.startswith("check_"): hint = "check_{}".format(hint) self._ac_check_result.append({"name": hint, "result": result.val}) + dataset.set_attr("access_control.build.acl.{}".format(element), result.hint) + dataset.set_attr("access_control.build.content", self._ac_check_result) logger.debug("ac result: {}".format(self._ac_check_result)) def load_check_elements_from_acl_directory(self, acl_dir): @@ -107,15 +116,16 @@ class AC(object): if os.path.isdir(os.path.join(acl_dir, filename)): self._ac_check_elements[filename] = {} # don't worry, using default when checking - def load_check_elements_from_conf(self, conf_file): + def load_check_elements_from_conf(self, conf_file, community): """ 加载门禁项目,只支持yaml格式 :param conf_file: 配置文件路径 + :param community: src-openeuler or openeuler :return: """ try: with open(conf_file, "r") as f: - elements = yaml.safe_load(f) + content = yaml.safe_load(f) except IOError: logger.exception("ac conf file {} not exist".format(conf_file)) return @@ -123,6 +133,8 @@ class AC(object): logger.exception("illegal conf file format") return + elements = content.get(community, {}) + logger.debug("community \"{}\" conf: {}".format(community, elements)) for name in elements: if name in self._ac_check_elements: if elements[name].get("exclude"): @@ -142,16 +154,34 @@ class AC(object): f.write("ACL={}".format(json.dumps(self._ac_check_result))) -if "__main__" == __name__: +def init_args(): + """ + init args + :return: + """ args = argparse.ArgumentParser() + args.add_argument("-c", type=str, dest="community", default="src-openeuler", help="src-openeuler or openeuler") args.add_argument("-w", type=str, dest="workspace", help="workspace where to find source") args.add_argument("-r", type=str, dest="repo", help="repo name") args.add_argument("-b", type=str, dest="tbranch", help="branch merge to") - args.add_argument("-n", type=str, dest="owner", default="src-openeuler", help="gitee owner") args.add_argument("-o", type=str, dest="output", help="output file to save result") args.add_argument("-p", type=str, dest="pr", help="pull request number") args.add_argument("-t", type=str, dest="token", help="gitee api token") - args = args.parse_args() + args.add_argument("-a", type=str, dest="account", help="gitee account") + + # dataset + args.add_argument("-m", type=str, dest="comment", help="trigger comment") + args.add_argument("-i", type=str, dest="comment_id", help="trigger comment id") + args.add_argument("-e", type=str, dest="committer", help="committer") + args.add_argument("-x", type=str, dest="pr_ctime", help="pr create time") + args.add_argument("-z", type=str, dest="trigger_time", help="job trigger time") + args.add_argument("-l", type=str, dest="trigger_link", help="job trigger link") + + return args.parse_args() + + +if "__main__" == __name__: + args = init_args() # init logging _ = not os.path.exists("log") and os.mkdir("log") @@ -163,11 +193,59 @@ if "__main__" == __name__: # notify gitee from src.proxy.gitee_proxy import GiteeProxy - gp = GiteeProxy(args.owner, args.repo, args.token) + from src.proxy.git_proxy import GitProxy + from src.proxy.es_proxy import ESProxy + from src.utils.dist_dataset import DistDataset + + dd = DistDataset() + dd.set_attr_stime("access_control.job.stime") + + # info from args + dd.set_attr("id", args.comment_id) + dd.set_attr("pull_request.package", args.repo) + dd.set_attr("pull_request.number", args.pr) + dd.set_attr("pull_request.author", args.committer) + dd.set_attr("pull_request.target_branch", args.tbranch) + dd.set_attr("pull_request.ctime", args.pr_ctime) + dd.set_attr("access_control.trigger.link", args.trigger_link) + dd.set_attr("access_control.trigger.reason", args.comment) + ctime = datetime.datetime.strptime(args.trigger_time.split("+")[0], "%Y-%m-%dT%H:%M:%S") + dd.set_attr_ctime("access_control.job.ctime", ctime) + + ep = ESProxy(os.environ["ESUSERNAME"], os.environ["ESPASSWD"], os.environ["ESURL"], verify_certs=False) + + # download repo + dd.set_attr_stime("access_control.scm.stime") + gp = GitProxy.init_repository(args.repo, work_dir=args.workspace) + repo_url = "https://{}@gitee.com/{}/{}.git".format(args.account, args.community, args.repo) + if not gp.fetch_pull_request(repo_url, args.pr, depth=4): + dd.set_attr("access_control.scm.result", "failed") + dd.set_attr_etime("access_control.scm.etime") + + dd.set_attr_etime("access_control.job.etime") + dd.set_attr("access_control.job.result", "successful") + ep.insert(index="openeuler_statewall_ac", body=dd.to_dict()) + sys.exit(-1) + else: + gp.checkout_to_commit_force("pull/{}/MERGE".format(args.pr)) + dd.set_attr("access_control.scm.result", "successful") + dd.set_attr_etime("access_control.scm.etime") + + # build start + dd.set_attr_stime("access_control.build.stime") + + # gitee pr tag + gp = GiteeProxy(args.community, args.repo, args.token) gp.delete_tag_of_pr(args.pr, "ci_successful") gp.delete_tag_of_pr(args.pr, "ci_failed") gp.create_tags_of_pr(args.pr, "ci_processing") - ac = AC(os.path.join(os.path.dirname(os.path.realpath(__file__)), "ac.yaml")) - ac.check_all(workspace=args.workspace, repo=args.repo, tbranch=args.tbranch) + # build + ac = AC(os.path.join(os.path.dirname(os.path.realpath(__file__)), "ac.yaml"), args.community) + ac.check_all(workspace=args.workspace, repo=args.repo, dataset=dd, tbranch=args.tbranch) + dd.set_attr_etime("access_control.build.etime") ac.save(args.output) + + dd.set_attr_etime("access_control.job.etime") + dd.set_attr("access_control.job.result", "successful") + ep.insert(index="openeuler_statewall_ac", body=dd.to_dict()) diff --git a/src/ac/framework/ac.yaml b/src/ac/framework/ac.yaml index 1785f2d14b5a012dbc7d769469c1af70ccc71ca5..8a229052ac8c8fadcfa5ccab544b24a7a2dbd136 100644 --- a/src/ac/framework/ac.yaml +++ b/src/ac/framework/ac.yaml @@ -1,11 +1,30 @@ -spec: - hint: check_spec_file - module: spec.check_spec - entry: CheckSpec - ignored: ["homepage"] -code: - hint: check_code_style - module: code.check_code_style - entry: CheckCodeStyle - #exclude: True - ignored: [] +src-openeuler: + spec: + hint: check_spec_file + module: spec.check_spec + entry: CheckSpec + ignored: ["homepage"] + code: + hint: check_code_style + module: code.check_code_style + entry: CheckCodeStyle + #exclude: True + ignored: [] + package_yaml: + hint: check_package_yaml_file + module: package_yaml.check_yaml + entry: CheckPackageYaml + ignored: ["fields"] + package_license: + hint: check_package_license + module: package_license.check_license + entry: CheckLicense +openeuler: + spec: + exclude: True + code: + exclude: True + package_yaml: + exclude: True + package_license: + exclude: True diff --git a/src/build/gitee_comment.py b/src/build/gitee_comment.py index 01c09ce5d806db9468b97f31e855f3650ce4143f..edb49b243ebdfd1494d185e4918e51d4e10fbae6 100755 --- a/src/build/gitee_comment.py +++ b/src/build/gitee_comment.py @@ -52,6 +52,8 @@ class Comment(object): comments = self._comment_build_html_format() gitee_proxy.comment_pr(self._pr, "\n".join(comments)) + return "\n".join(comments) + def comment_at(self, committer, gitee_proxy): """ 通知committer @@ -228,9 +230,14 @@ class Comment(object): return "{} {}{}".format(name, icon, status) -if "__main__" == __name__: +def init_args(): + """ + init args + :return: + """ args = argparse.ArgumentParser() args.add_argument("-p", type=int, dest="pr", help="pull request number") + args.add_argument("-m", type=int, dest="comment_id", help="uniq comment id") args.add_argument("-c", type=str, dest="committer", help="commiter") args.add_argument("-o", type=str, dest="owner", help="gitee owner") args.add_argument("-r", type=str, dest="repo", help="repo name") @@ -244,8 +251,11 @@ if "__main__" == __name__: args.add_argument("--disable", dest="enable", default=True, action="store_false", help="comment to gitee switch") - args = args.parse_args() + return args.parse_args() + +if "__main__" == __name__: + args = init_args() if not args.enable: sys.exit(0) @@ -256,25 +266,49 @@ if "__main__" == __name__: from src.ac.framework.ac_result import ACResult, SUCCESS from src.proxy.gitee_proxy import GiteeProxy + from src.proxy.es_proxy import ESProxy from src.proxy.jenkins_proxy import JenkinsProxy + from src.utils.dist_dataset import DistDataset - # gitee notify + dd = DistDataset() + dd.set_attr_stime("comment.job.stime") + + # gitee pr tag gp = GiteeProxy(args.owner, args.repo, args.gitee_token) gp.delete_tag_of_pr(args.pr, "ci_processing") - jp = JenkinsProxy(args.jenkins_base_url, args.jenkins_user, args.jenkins_api_token) + url, build_time, reason = jp.get_job_build_info(os.environ.get("JOB_NAME"), int(os.environ.get("BUILD_ID"))) + dd.set_attr("comment.job.link", url) + dd.set_attr("comment.trigger.reason", reason) + dd.set_attr_ctime("comment.job.ctime", build_time) - if args.check_abi_comment_files: - comment = Comment(args.pr, jp, *args.check_abi_comment_files) - else: - comment = Comment(args.pr, jp) - logger.info("comment: build result......") - comment.comment_build(gp) + dd.set_attr_stime("comment.build.stime") + comment = Comment(args.pr, jp, *args.check_abi_comment_files) \ + if args.check_abi_comment_files else Comment(args.pr, jp) + logger.info("comment: build result......") + content = comment.comment_build(gp) + dd.set_attr_etime("comment.build.etime") + dd.set_attr("comment.build.content.html", content) + if comment.check_build_result() == SUCCESS: gp.create_tags_of_pr(args.pr, "ci_successful") + dd.set_attr("comment.build.tags", ["ci_successful"]) + dd.set_attr("comment.build.result", "successful") else: gp.create_tags_of_pr(args.pr, "ci_failed") + dd.set_attr("comment.build.tags", ["ci_failed"]) + dd.set_attr("comment.build.result", "failed") + logger.info("comment: at committer......") comment.comment_at(args.committer, gp) + + dd.set_attr_etime("comment.job.etime") + dd.set_attr("comment.job.result", "successful") + + # upload to es + ep = ESProxy(os.environ["ESUSERNAME"], os.environ["ESPASSWD"], os.environ["ESURL"], verify_certs=False) + query = {"term": {"id": args.comment_id}} + script = {"lang": "painless", "source": "ctx._source.comment = params.comment", "params": dd.to_dict()} + ep.update_by_query(index="openeuler_statewall_ac", query=query, script=script) diff --git a/src/build/osc_build_k8s.py b/src/build/osc_build_k8s.py index de36b28b71714ac60187870c125d77e0e18f09c7..fa024df31e5547758b4cbdb3a8a29c471e70ff1e 100755 --- a/src/build/osc_build_k8s.py +++ b/src/build/osc_build_k8s.py @@ -28,12 +28,13 @@ class SinglePackageBuild(object): """ GITEE_BRANCH_PROJECT_MAPPING = { - "master": ["bringInRely", "openEuler:Extras", "openEuler:Factory", "openEuler:Mainline"], + "master": ["bringInRely", "openEuler:Extras", "openEuler:Factory", "openEuler:Mainline", "openEuler:Epol"], "openEuler-20.03-LTS": ["openEuler:20.03:LTS"], - "openEuler-20.03-LTS-Next": ["openEuler:20.03:LTS:Next"], + "openEuler-20.03-LTS-Next": ["openEuler:20.03:LTS:Next", "openEuler:20.03:LTS:Next:Epol"], "openEuler-EPOL-LTS": ["bringInRely"], - "openEuler-20.09": ["openEuler:20.09"], - "mkopeneuler-20.03": ["openEuler:Extras"] + "openEuler-20.09": ["openEuler:20.09", "openEuler:20.09:Epol"], + "mkopeneuler-20.03": ["openEuler:Extras"], + "openEuler-20.03-LTS-SP1": ["openEuler:20.03:LTS:SP1", "openEuler:20.03:LTS:SP1:Epol"] } BUILD_IGNORED_GITEE_BRANCH = ["riscv"] @@ -137,6 +138,7 @@ class SinglePackageBuild(object): param.text = "tar_local" elif param.get("name") == "url": if "openEuler_kernel" in param.text or "LTS_kernel" in param.text \ + or "openEuler-kernel" in param.text \ or "openEuler-20.09_kernel" in param.text: param.text = "{}/{}".format(code_path, "code") # kernel special logical else: @@ -180,11 +182,11 @@ class SinglePackageBuild(object): """ if self._branch in self.BUILD_IGNORED_GITEE_BRANCH: logger.error("branch \"{}\" ignored".format(self._branch)) - sys.exit(0) + return 0 if self._branch not in self.GITEE_BRANCH_PROJECT_MAPPING: logger.error("branch \"{}\" not support yet".format(self._branch)) - sys.exit(1) + return 1 for project in self.GITEE_BRANCH_PROJECT_MAPPING.get(self._branch): logger.debug("start build project {}".format(project)) @@ -199,12 +201,18 @@ class SinglePackageBuild(object): if ret > 0: logger.debug("build run return {}".format(ret)) logger.error("build {} {} {} ... {}".format(project, self._package, self._arch, "failed")) - sys.exit(1) # finish if any error + return 1 # finish if any error else: logger.info("build {} {} {} ... {}".format(project, self._package, self._arch, "ok")) + return 0 + -if "__main__" == __name__: +def init_args(): + """ + init args + :return: + """ args = argparse.ArgumentParser() args.add_argument("-p", type=str, dest="package", help="obs package") @@ -213,15 +221,66 @@ if "__main__" == __name__: args.add_argument("-c", type=str, dest="code", help="code dir path") args.add_argument("-w", type=str, dest="workspace", default=os.getcwd(), help="obs workspace dir path") - args = args.parse_args() + args.add_argument("-m", type=str, dest="comment_id", help="uniq comment id") + args.add_argument("-r", type=str, dest="repo", help="repo") + args.add_argument("--pr", type=str, dest="pr", help="pull request") + args.add_argument("-t", type=str, dest="account", help="gitee account") + + args.add_argument("-o", type=str, dest="owner", default="src-openeuler", help="gitee owner") + + return args.parse_args() + + +if "__main__" == __name__: + args = init_args() _ = not os.path.exists("log") and os.mkdir("log") logger_conf_path = os.path.realpath(os.path.join(os.path.realpath(__file__), "../../conf/logger.conf")) logging.config.fileConfig(logger_conf_path) logger = logging.getLogger("build") + from src.utils.dist_dataset import DistDataset + from src.proxy.git_proxy import GitProxy from src.proxy.obs_proxy import OBSProxy + from src.proxy.es_proxy import ESProxy from src.utils.shell_cmd import shell_cmd_live + dd = DistDataset() + dd.set_attr_stime("spb.job.stime") + + ep = ESProxy(os.environ["ESUSERNAME"], os.environ["ESPASSWD"], os.environ["ESURL"], verify_certs=False) + + # download repo + dd.set_attr_stime("spb.scm.stime") + gp = GitProxy.init_repository(args.repo, work_dir=args.workspace) + repo_url = "https://{}@gitee.com/{}/{}.git".format(args.account, args.owner, args.repo) + if not gp.fetch_pull_request(repo_url, args.pr, depth=1): + dd.set_attr("spb.scm.result", "failed") + dd.set_attr_etime("spb.scm.etime") + dd.set_attr_etime("spb.job.etime") + dd.set_attr("spb.job.result", "failed") + + # upload to es + query = {"term": {"id": args.comment_id}} + script = {"lang": "painless", "source": "ctx._source.spb_{}=params.spb".format(args.arch), + "params": dd.to_dict()} + ep.update_by_query(index="openeuler_statewall_ac", query=query, script=script) + sys.exit(-1) + else: + gp.checkout_to_commit_force("pull/{}/MERGE".format(args.pr)) + dd.set_attr("spb.scm.result", "successful") + dd.set_attr_etime("spb.scm.etime") + + dd.set_attr_stime("spb.build.stime") spb = SinglePackageBuild(args.package, args.arch, args.branch) - spb.build(args.workspace, args.code) + rs = spb.build(args.workspace, args.code) + dd.set_attr("spb.job.result", "failed" if rs else "successful") + dd.set_attr_etime("spb.build.etime") + + dd.set_attr_etime("spb.job.etime") + + # upload to es + query = {"term": {"id": args.comment_id}} + script = {"lang": "painless", "source": "ctx._source.spb_{}=params.spb".format(args.arch), "params": dd.to_dict()} + ep.update_by_query(index="openeuler_statewall_ac", query=query, script=script) + sys.exit(rs) diff --git a/src/build/related_rpm_package.py b/src/build/related_rpm_package.py index 91aeefd7143b624314a2cffbf7682a0f9f5080f8..627000a9e904804e426a132fee93fb3dca603a84 100755 --- a/src/build/related_rpm_package.py +++ b/src/build/related_rpm_package.py @@ -36,7 +36,8 @@ class RelatedRpms(object): "openEuler-20.03-LTS-Next": ["openEuler:20.03:LTS:Next"], "openEuler-EPOL-LTS": ["bringInRely"], "openEuler-20.09": ["openEuler:20.09"], - "mkopeneuler-20.03": ["openEuler:Extras"] + "mkopeneuler-20.03": ["openEuler:Extras"], + "openEuler-20.03-LTS-SP1": ["openEuler:20.03:LTS:SP1"] } def __init__(self, obs_addr, obs_repo_url, branch_name, package_arch): diff --git a/src/dockerfile/openeuler-base b/src/dockerfile/jenkins-openeuler similarity index 90% rename from src/dockerfile/openeuler-base rename to src/dockerfile/jenkins-openeuler index 88c94fd68c5f57a8e3e295b351c99e24f4498996..98ffa419b8a475cb358da0c1b71288e2162e4a9c 100644 --- a/src/dockerfile/openeuler-base +++ b/src/dockerfile/jenkins-openeuler @@ -1,4 +1,5 @@ -FROM swr.cn-north-4.myhuaweicloud.com/openeuler/openjdk-openeuler:11-jdk-stretch +# replace VERSION before run +FROM swr.cn-north-4.myhuaweicloud.com/openeuler/openeuler-VERSION/openjdk:11-jdk-stretch ARG VERSION=4.3 ARG user=jenkins @@ -7,8 +8,6 @@ ARG uid=1000 ARG gid=1000 ARG AGENT_WORKDIR=/home/${user}/agent -RUN yum install -y shadow git - RUN curl --create-dirs -fsSLo /usr/share/jenkins/agent.jar https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/${VERSION}/remoting-${VERSION}.jar \ && chmod 755 /usr/share/jenkins \ && chmod 644 /usr/share/jenkins/agent.jar \ diff --git a/src/dockerfile/openjdk-openeuler b/src/dockerfile/openjdk-openeuler index 1f264e30fd16e103f0dcf13b5dadcfdf50efdf4b..aaf591440970344bdbaf2421b89b9eb8caef92bc 100644 --- a/src/dockerfile/openjdk-openeuler +++ b/src/dockerfile/openjdk-openeuler @@ -1,7 +1,8 @@ -FROM swr.cn-north-4.myhuaweicloud.com/openeuler/openeuler:20.03-lts-08-20 +# replace VERSION before build +FROM swr.cn-north-4.myhuaweicloud.com/openeuler/openeuler:VERSION RUN set -eux; \ - yum install -y tar wget + yum install -y tar wget python3 expect osc vim openssh shadow git # Default to UTF-8 file.encoding ENV LANG C.UTF-8 diff --git a/src/jenkinsfile/openeuler_jenkins_test.py b/src/jenkinsfile/openeuler_jenkins_test.py new file mode 100644 index 0000000000000000000000000000000000000000..88d5ee81306b3ceb6b88aa593a2773ca7cecc33e --- /dev/null +++ b/src/jenkinsfile/openeuler_jenkins_test.py @@ -0,0 +1,46 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-21 +# Description: run all test cases in test/ +# ***********************************************************************************/ +""" + +import os +import unittest +import logging.config +import logging +import mock +import shutil + +PATTERN_STR = 'test*.py' # 测试用例文件必须以test_开头 +TEST_DIR = os.path.realpath(os.path.join(os.path.realpath(__file__), '..', '..', '..', 'test')) +LOG_FILE = os.path.realpath(os.path.join(os.path.realpath(__file__), '..', 'test.log')) + +if __name__ == '__main__': + # mock所有logger为测试使用logger,输出为该文件同目录下的test.log + wordk_dir = os.getcwd() + _ = not os.path.exists("log") and os.mkdir("log") + logger_conf_path = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../conf/logger.conf")) + logging.config.fileConfig(logger_conf_path) + logger = logging.getLogger("test_logger") + + # 递归获取test目录下所有module的所有测试用例(需包含__init__.py) + discover_sets = unittest.defaultTestLoader.discover(start_dir=TEST_DIR, pattern=PATTERN_STR, top_level_dir=None) + suite = unittest.TestSuite() + suite.addTest(discover_sets) + # 运行所有测试用例 + test_runner = unittest.TextTestRunner() + test_runner.run(suite) + os.chdir(wordk_dir) + shutil.rmtree("log") \ No newline at end of file diff --git a/src/proxy/es_proxy.py b/src/proxy/es_proxy.py new file mode 100644 index 0000000000000000000000000000000000000000..0304dcaabc772696a06bc696878a8cedc193787c --- /dev/null +++ b/src/proxy/es_proxy.py @@ -0,0 +1,101 @@ +# -*- encoding=utf-8 -*- +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-12-30 +# Description: elasticsearch proxy +# ********************************************************************************** + +import logging +from elasticsearch import Elasticsearch, RequestError + +logger = logging.getLogger("common") + + +class ESProxy(object): + """ + es 代理 + """ + def __init__(self, username, password, hosts=None, timeout=30, **kwargs): + """ + + :param username: + :param password: + :param hosts: 参考Elasticsearch.__init__描述 + :param timeout: + """ + + self._timeout = timeout + self._es = Elasticsearch(hosts=hosts, http_auth=(username, password), timeout=self._timeout, **kwargs) + + def insert(self, index, body): + """ + 插入一条数据 + :param index: + :param body: + :return: + """ + try: + rs = self._es.index(index, body=body) + + return rs["result"] == "created" + except RequestError: + logger.exception("elasticsearch insert document exception") + return False + + def search(self, index, body): + """ + 条件搜索 + :param index: + :param body: + :return: + """ + rs = self._es.search(index=index, body=body) + + return rs['hits']['hits'] + + def update_by_query(self, index, query, script): + """ + 更新一条数据,原数据不变 + eg: + query = { + "term": {"id": 567} + } + script = { + "source": "ctx._source.tags = params.tags", + "params": { + "tags": tags + }, + "lang":"painless" + } + :param index: + :param query: + :param script: + :return: + """ + body = {"query": query, "script": script} + try: + rs = self._es.update_by_query(index, body=body) + logger.debug("elasticsearch update {} documents".format(rs["updated"])) + + return True + except RequestError: + logger.exception("elasticsearch update by query exception") + return False + + +host="https://119.8.112.14:9200" +pwd="Cloudfoundry@123" + +es = Elasticsearch(hosts=host, http_auth=("admin", pwd), verify_certs=False) +i = "openeuler_statewall_ac" +from pprint import pprint +pprint(es.search(index=i, body={"query": {"term": {"id": 9999}}})["hits"]["hits"]) diff --git a/src/proxy/git_proxy.py b/src/proxy/git_proxy.py index 712f45e5684e3e97a6f2a71df89d93db37bec1bc..204ab371499ee528c18f7bfd7743b1f2de32b0bf 100644 --- a/src/proxy/git_proxy.py +++ b/src/proxy/git_proxy.py @@ -1,4 +1,5 @@ # -*- encoding=utf-8 -*- +import os import logging from cStringIO import StringIO @@ -17,6 +18,43 @@ class GitProxy(object): """ self._repo_dir = repo_dir + @classmethod + def init_repository(cls, sub_dir, work_dir=None): + """ + 初始化git仓库 + :param sub_dir: 仓库子目录 + :param work_dir: 仓库根目录 + :return: GitProxy() or None + """ + repo_dir = os.path.join(work_dir, sub_dir) if work_dir else sub_dir + + init_cmd = "git init {}".format(repo_dir) + ret, _, _ = shell_cmd_live(init_cmd) + + if ret: + logger.warning("init repository failed, {}".format(ret)) + return None + + return cls(repo_dir) + + def fetch_pull_request(self, url, pull_request, depth=1, progress=False): + """ + fetch pr + :param url: 仓库地址 + :param pull_request: pr编号 + :param depth: 深度 + :param progress: 展示进度 + :return: + """ + fetch_cmd = "cd {}; git fetch {} --depth {} {} +refs/pull/{}/MERGE:refs/pull/{}/MERGE".format( + self._repo_dir, "--progress" if progress else "", depth, url, pull_request, pull_request) + ret, _, _ = shell_cmd_live(fetch_cmd, cap_out=True, cmd_verbose=False) + if ret: + logger.error("git fetch failed, {}".format(ret)) + return False + + return True + def get_content_of_file_with_commit(self, file_path, commit="HEAD~0"): """ 获取单个commit文件内容 @@ -132,6 +170,21 @@ class GitProxy(object): return True + def checkout_to_commit_force(self, commit): + """ + git checkout + :param commit: HEAD~{} or SHA + :return: boolean + """ + checkout_cmd = "cd {}; git checkout -f {}".format(self._repo_dir, commit) + ret, _, _ = shell_cmd_live(checkout_cmd) + + if ret: + logger.warning("checkout failed, {}".format(ret)) + return False + + return True + def get_tree_hashes(self, commit, number=0, with_merges=True): """ 获取tree对象hash值 diff --git a/src/proxy/jenkins_proxy.py b/src/proxy/jenkins_proxy.py index 63fd8efa56a085cf6fd6839647cb4ca387cd61f9..b4b035bd1cc2a9c1c9629217dacc468a1ea7543b 100644 --- a/src/proxy/jenkins_proxy.py +++ b/src/proxy/jenkins_proxy.py @@ -22,6 +22,7 @@ import re # not friendly when job in folders import jenkinsapi.jenkins as jenkins import src.proxy.jenkins_patch +from src.utils.dt_transform import convert_utc_to_naive logger = logging.getLogger("common") @@ -181,3 +182,52 @@ class JenkinsProxy(object): break return upstream_builds + + def get_job_url(self, job): + """ + 获取任务url + :param job: + :return: + """ + j = self._jenkins[job] + + return self._jenkins[job].url + + def get_build_datetime(self, job, build): + """ + get job build tims + :param job: + :param build: + :return: + """ + return convert_utc_to_naive(self._jenkins[job].get_build(build).get_timestamp()) + + def get_build_trigger_reason(self, job, build): + """ + get job build tims + :param job: + :param build: + :return: + """ + causes = self._jenkins[job].get_build(build).get_causes() + if not causes: + return "N/A" + + return causes[0]["shortDescription"] + + def get_job_build_info(self, job, build): + """ + get job and build info + :param job: + :param build: + :return: + """ + job = self._jenkins[job] + build = job.get_build(build) + + build_dt = convert_utc_to_naive(build.get_timestamp()) + + causes = build.get_causes() + trigger_reason = causes[0]["shortDescription"] if causes else "N/A" + + return job.url, build_dt, trigger_reason diff --git a/src/proxy/obs_proxy.py b/src/proxy/obs_proxy.py index 15a8fedb702ba1436465ae30d1721d0d7935f75a..eee8ad139bcdf070d7565678d533e871052c8cc1 100644 --- a/src/proxy/obs_proxy.py +++ b/src/proxy/obs_proxy.py @@ -132,3 +132,21 @@ class OBSProxy(object): return False return True + + @staticmethod + def build_history(project, package, repo, arch): + """ + 构建历史 + :param project: + :param package: + :param repo: + :param arch: + :return: + """ + cmd = "osc api /build/{}/{}/{}/{}/_history".format(project, repo, arch, package) + ret, out, _ = shell_cmd_live(cmd, cap_out=True) + if ret: + logger.debug("list build history of package error, {}".format(ret)) + return "" + + return "\n".join(out) diff --git a/src/requirements b/src/requirements index 30e813f0c12d1fb314fa1391865566e27fe019df..34e139555ef82db1274bee08b2b88dd6eb2d7706 100644 --- a/src/requirements +++ b/src/requirements @@ -5,3 +5,6 @@ threadpool PyYAML gevent==1.2.2 jsonpath +mock +tldextract +chardet \ No newline at end of file diff --git a/src/tools/obs_package_build_history.py b/src/tools/obs_package_build_history.py new file mode 100644 index 0000000000000000000000000000000000000000..cd0863785e49dae50e791b254884c10227969e8c --- /dev/null +++ b/src/tools/obs_package_build_history.py @@ -0,0 +1,130 @@ +# -*- encoding=utf-8 -*- +""" +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-09-29 +# Description: report obs package build info +# ********************************************************************************** +""" + +import gevent +from gevent import monkey +monkey.patch_all() +import logging.config +import logging +import os +import argparse +import time +import xml.etree.ElementTree as ET +from xml.etree.ElementTree import ParseError +import json + +logger = logging.getLogger("common") + + +class JobBuildHistory(object): + @staticmethod + def get_package_job_duration(project, package, repo, arch): + """ + 获取任务构建时间信息 + :param project: + :param package: + :param repo: + :param arch: + :return: + """ + history = OBSProxy.build_history(project, package, repo, arch) + try: + root = ET.fromstring(history) + except ParseError: + logger.exception("package: {}, build history: {}".format(package, history)) + return {"package": package, "max": 0, "min": 0, "average": 0, "times": -1} + + duration = [int(ele.get("duration")) for ele in root.findall("entry")] + + if not duration: + return {"package": package, "max": 0, "min": 0, "average": 0, "times": 0, "duration": []} + + return {"package": package, "max": max(duration), "min": min(duration), "duration": duration, + "average": sum(duration) / len(duration), "times": len(duration)} + + @staticmethod + def get_packages_job_duration(project, repo, arch, concurrency, *packages): + """ + 获取多个包任务构建时间信息 + :param project: + :param packages: + :param repo: + :param arch: + :param concurrency: + :return: + """ + batch = (len(packages) + concurrency - 1) / concurrency + + rs = [] + for index in range(batch): + works = [gevent.spawn(JobBuildHistory.get_package_job_duration, project, package, repo, arch) + for package in packages[index * concurrency: (index + 1) * concurrency]] + logger.info("{} works, {}/{} ".format(len(works), index + 1, batch)) + gevent.joinall(works) + for work in works: + logger.debug("{}: {}".format(work.value["package"], work.value)) + logger.info("{} ...done".format(work.value["package"])) + rs.append(work.value) + + time.sleep(1) + + rs.sort(key=lambda item: item["max"]) + return rs + + @staticmethod + def get_jobs_duration(project, repo, arch, concurrency=50): + """ + 获取项目下所有包构建时间信息 + :param project: + :param repo: + :param arch: + :return: + """ + packages = OBSProxy.list_project(project) + + return JobBuildHistory.get_packages_job_duration(project, repo, arch, concurrency, *packages) + + +if "__main__" == __name__: + args = argparse.ArgumentParser() + + args.add_argument("-p", type=str, dest="project", help="obs project") + args.add_argument("-g", type=str, dest="packages", nargs="+", help="package") + args.add_argument("-r", type=str, dest="repo", help="repo") + args.add_argument("-a", type=str, dest="arch", help="arch") + args.add_argument("-c", type=str, dest="concurrency", help="concurrency for obs") + args.add_argument("-o", type=str, dest="output", help="output file") + + args = args.parse_args() + + _ = not os.path.exists("log") and os.mkdir("log") + logger_conf_path = os.path.realpath(os.path.join(os.path.realpath(__file__), "../../conf/logger.conf")) + logging.config.fileConfig(logger_conf_path) + logger = logging.getLogger("build") + + from src.proxy.obs_proxy import OBSProxy + + if args.packages: + result = JobBuildHistory.get_packages_job_duration(args.project, args.repo, args.arch, + int(args.concurrency), *args.packages) + else: + result = JobBuildHistory.get_jobs_duration(args.project, args.repo, args.arch, int(args.concurrency)) + + if args.output: + with open(args.output, "w") as f: + json.dump(result, f) diff --git a/src/tools/obs_package_build_report.py b/src/tools/obs_package_build_report.py index 543af26fa27aa2fb4c1a2b68b8253465d3f419c2..c209f1735cdb7eeab4182c37893a7738e6f305d3 100644 --- a/src/tools/obs_package_build_report.py +++ b/src/tools/obs_package_build_report.py @@ -32,8 +32,14 @@ class ObsPackageBuildReport(object): PROJECT_BRANCH_MAPPING = { "openEuler:Factory": "master", "openEuler:Mainline": "master", + "openEuler:Epol": "master", "openEuler:20.03:LTS": "openEuler-20.03-LTS", - "openEuler:20.09": "openEuler-20.09" + "openEuler:20.09": "openEuler-20.09", + "openEuler:20.09:Epol": "openEuler-20.09", + "openEuler:20.03:LTS:Next": "openEuler-20.03-LTS-Next", + "openEuler:20.03:LTS:Next:Epol": "openEuler-20.03-LTS-Next", + "openEuler:20.03:LTS:SP1": "openEuler-20.03-LTS-SP1", + "openEuler:20.03:LTS:SP1:Epol": "openEuler-20.03-LTS-SP1" } GITEE_OWNER = "src-openeuler" @@ -74,11 +80,12 @@ class ObsPackageBuildReport(object): :param gitee_api_token: 码云api token :return: """ - try: - branch = self.__class__.PROJECT_BRANCH_MAPPING[self._project] - except KeyError: - logger.exception("project {} not support".format(self._project)) - return +# try: +# branch = self.__class__.PROJECT_BRANCH_MAPPING[self._project] +# except KeyError: +# logger.exception("project {} not support".format(self._project)) +# return + branch = "master" # get packages in project of state packages = OBSProxy.list_packages_of_state(self._project, self._state) @@ -122,8 +129,8 @@ if "__main__" == __name__: from src.proxy.obs_proxy import OBSProxy from src.proxy.gitee_proxy import GiteeProxy - for project in args.project: - for state in args.state: - report = ObsPackageBuildReport(project, state, args.real_name_mapping_file) + for prj in args.project: + for states in args.state: + report = ObsPackageBuildReport(prj, states, args.real_name_mapping_file) report.get_last_committer(args.token) report.dump() diff --git a/src/utils/check_conf.py b/src/utils/check_conf.py index 9a181bdde0be6cafe31f4007a639c02d8559d924..3b65c80fafb43c1b0a81b1b59b325a493077abc7 100755 --- a/src/utils/check_conf.py +++ b/src/utils/check_conf.py @@ -96,8 +96,8 @@ class CheckConfig(object): """ Check md5sum """ - old_md5 = subprocess.run(['md5sum', old_rpm], stdout=subprocess.PIPE, encoding='utf-8') - new_md5 = subprocess.run(['md5sum', new_rpm], stdout=subprocess.PIPE, encoding='utf-8') + old_md5 = subprocess.run(['md5sum', old_rpm], stdout=subprocess.PIPE) + new_md5 = subprocess.run(['md5sum', new_rpm], stdout=subprocess.PIPE) return old_md5.stdout.split()[0] == new_md5.stdout.split()[0] def _check_diff(self, old_and_new_path): @@ -105,6 +105,7 @@ class CheckConfig(object): Check diff file """ for name in self._need_check_file: + logging.info("config file:%s", name) name = name.split("/", 1)[-1].split()[0] logging.debug("path:%s", old_and_new_path) if self._md5_check(os.path.join(old_and_new_path[0], name), os.path.join(old_and_new_path[1], name)): @@ -162,6 +163,7 @@ class CheckConfig(object): logging.info("\n---Change infos write at:%s----", self._output_file) else: logging.info("\n---Configs are same----") + os.remove(self._output_file) ofile.close() def _get_rpms(self, rpm_url, dest): @@ -189,8 +191,8 @@ class CheckConfig(object): if self._md5_check(self._old_rpm, self._new_rpm): logging.info("Same RPM") return - old_config = subprocess.run(['rpm', '-qpc', self._old_rpm], stdout=subprocess.PIPE, encoding='utf-8') - new_config = subprocess.run(['rpm', '-qpc', self._new_rpm], stdout=subprocess.PIPE, encoding='utf-8') + old_config = subprocess.run(['rpm', '-qpc', self._old_rpm], stdout=subprocess.PIPE) + new_config = subprocess.run(['rpm', '-qpc', self._new_rpm], stdout=subprocess.PIPE) for line in old_config.stdout.split(): self._remove_file.add(line) for line in new_config.stdout.split(): diff --git a/src/utils/dist_dataset.py b/src/utils/dist_dataset.py new file mode 100644 index 0000000000000000000000000000000000000000..64e160338c78cd36eb15923225449e23fa581dda --- /dev/null +++ b/src/utils/dist_dataset.py @@ -0,0 +1,111 @@ +# -*- encoding=utf-8 -*- +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-09-23 +# Description: gitee api proxy +# ********************************************************************************** + +import logging +from datetime import datetime + +from src.utils.dot_json import MutableDotJson + +logger = logging.getLogger("common") + + +class DistDataset(object): + """ + 分布式数据集,用来保存门禁各阶段性结果 + """ + def __init__(self): + """ + 初始化 + """ + self._json = MutableDotJson() + + def to_dict(self): + """ + + :return: + """ + return self._json.to_dict() + + def set_attr(self, attr, value): + """ + 属性赋值 + :param attr: 属性 + :param value: 值 + :return: + """ + self._json[attr] = value + + def set_attr_ctime(self, attr, ctime): + """ + 属性【开始时间】赋值 + :param attr: + :param ctime: jenkins build time + :return: + """ + self._json[attr] = ctime.strftime("%Y-%m-%d %H:%M:%S") + + attrs = attr.split(".") + # set pending + attrs[-1] = "stime" + try: + stime_str = self._json[".".join(attrs)] + stime = datetime.strptime(stime_str, "%Y-%m-%d %H:%M:%S") + pending = (stime - ctime).total_seconds() # seconds + attrs[-1] = "pending" + self._json[".".join(attrs)] = int(pending) + except KeyError: + logger.debug("no correspond stime") + + def set_attr_stime(self, attr): + """ + 属性【开始时间】赋值 + :param attr: + :return: + """ + now = datetime.now() + self._json[attr] = now.strftime("%Y-%m-%d %H:%M:%S") + + def set_attr_etime(self, attr): + """ + 属性【结束时间】赋值 + :param attr: + :return: + """ + now = datetime.now() + self._json[attr] = now.strftime("%Y-%m-%d %H:%M:%S") + + attrs = attr.split(".") + # set elapse + attrs[-1] = "stime" + try: + stime_str = self._json[".".join(attrs)] + stime = datetime.strptime(stime_str, "%Y-%m-%d %H:%M:%S") + elapse = (now - stime).total_seconds() # seconds + attrs[-1] = "elapse" + self._json[".".join(attrs)] = int(elapse) + except KeyError: + logger.debug("no correspond stime") + + # set interval + attrs[-1] = "ctime" + try: + ctime_str = self._json[".".join(attrs)] + ctime = datetime.strptime(ctime_str, "%Y-%m-%d %H:%M:%S") + elapse = (now - ctime).total_seconds() # seconds + attrs[-1] = "interval" + self._json[".".join(attrs)] = int(elapse) + except KeyError: + logger.debug("no correspond ctime") diff --git a/src/utils/dot_json.py b/src/utils/dot_json.py new file mode 100644 index 0000000000000000000000000000000000000000..d51179edbd8cad0d3d35b4e28c16b745db04df57 --- /dev/null +++ b/src/utils/dot_json.py @@ -0,0 +1,128 @@ +# -*- encoding=utf-8 -*- +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-12-22 +# Description: one kind of json that support access value with continue dot attribute +# ********************************************************************************** + +from collections import Mapping, MutableSequence, MutableMapping + + +class DotJson(object): + """ + one kind of json that support access value with continue dot attribute + """ + def __init__(self, data=None): + """ + 初始化 + :param data: Mapping or Sequence + """ + if isinstance(data, Mapping): + self._data = dict(data) + elif isinstance(data, MutableSequence): + self._data = list(data) + elif data is None: + self._data = dict() + else: + raise Exception("init with type {} not support".format(type(data))) + + def to_dict(self): + """ + dict格式 + :return: + """ + return self._data + + def __str__(self): + """ + + :return: + """ + return str(self._data) + + def __getitem__(self, item): + """ + 支持"."符号连接的嵌套属性取值 + :param item: + :return: + """ + if isinstance(item, int): + return self.__class__.build(self._data[item]) + + s = self + for attr in item.split("."): # eg: item = "a.0.b" + s = s.get(attr) + + return s + + def get(self, item): + """ + 取值辅助函数 + :param item: + :return: + """ + if isinstance(self._data, MutableSequence) and item.isdigit(): # 嵌套属性中的数字分量 + item = int(item) + + return self.__class__.build(self._data[item]) + + def __getattr__(self, item): + """ + 获取属性 + :param item: + :return: + """ + try: + return self[item] + except (IndexError, KeyError, TypeError) as e: + raise AttributeError(e) + + @classmethod + def build(cls, obj): + """ + 自举 + :param obj: + :return: + """ + return cls(obj) if isinstance(obj, (Mapping, MutableSequence)) else obj + + +class MutableDotJson(DotJson): + """ + 可变 + """ + def __setitem__(self, key, value): + """ + 赋值 + :param key: + :param value: + :return: + """ + s = self._data + attrs = key.split(".") + for attr in attrs[:-1]: + if isinstance(s, MutableMapping): + if attr not in s: + s[attr] = {} + s = s[attr] + elif isinstance(s, MutableSequence): + if attr.isdigit(): + s = s[int(attr)] + else: + # set Sequence, but index is not digit + raise TypeError("list indices must be integers or slices, not str") + else: + # object is not Sequence or Mapping + raise TypeError("set value for {} not support".format(type(s))) + + last_attr = attrs[-1] + s[last_attr] = value diff --git a/src/utils/dt_transform.py b/src/utils/dt_transform.py new file mode 100644 index 0000000000000000000000000000000000000000..d0801350b57cdb42b35dbd284a39b4297c0f2743 --- /dev/null +++ b/src/utils/dt_transform.py @@ -0,0 +1,30 @@ +# -*- encoding=utf-8 -*- +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-09-23 +# Description: gitee api proxy +# ********************************************************************************** + +from datetime import datetime +import calendar + + +def convert_utc_to_naive(utc_dt): + """ + utc datetime to local datetime + :param utc_dt: utc datetime + :return: + """ + ts = calendar.timegm(utc_dt.timetuple()) + naive_dt = datetime.fromtimestamp(ts) + + return naive_dt.replace(microsecond=utc_dt.microsecond) diff --git a/src/utils/shell_cmd.py b/src/utils/shell_cmd.py index a6168f7c8b42ac5bda67bb4fe74d78455162d165..d3bc10cc92b5b8cb2678e8bd20326d23724438cd 100755 --- a/src/utils/shell_cmd.py +++ b/src/utils/shell_cmd.py @@ -18,7 +18,7 @@ def shell_cmd(cmd, inmsg=None): return p.returncode, out, err -def shell_cmd_live(cmd, cap_in=None, cap_out=False, cap_err=False, verbose=False): +def shell_cmd_live(cmd, cap_in=None, cap_out=False, cap_err=False, verbose=False, cmd_verbose=True): """ 创建子进程执行命令,实时输出结果 :param cmd: 命令 @@ -28,7 +28,8 @@ def shell_cmd_live(cmd, cap_in=None, cap_out=False, cap_err=False, verbose=False :param verbose: show cmd output to console, default not :return: """ - logger.debug("exec cmd -- {}".format(cmd)) + if cmd_verbose: + logger.debug("exec cmd -- {}".format(cmd)) p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) if cap_in: diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ed5bdad435b94b1475a582e9f6602dd020179de1 --- /dev/null +++ b/test/__init__.py @@ -0,0 +1,17 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-21 +# Description: +# ***********************************************************************************/ +""" \ No newline at end of file diff --git a/test/ac/__init__.py b/test/ac/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ed5bdad435b94b1475a582e9f6602dd020179de1 --- /dev/null +++ b/test/ac/__init__.py @@ -0,0 +1,17 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-21 +# Description: +# ***********************************************************************************/ +""" \ No newline at end of file diff --git a/test/ac/acl/__init__.py b/test/ac/acl/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ed5bdad435b94b1475a582e9f6602dd020179de1 --- /dev/null +++ b/test/ac/acl/__init__.py @@ -0,0 +1,17 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-21 +# Description: +# ***********************************************************************************/ +""" \ No newline at end of file diff --git a/test/ac/acl/license/__init__.py b/test/ac/acl/license/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..36e95ff3db7d173ff656de1605ce299b4e77f17a --- /dev/null +++ b/test/ac/acl/license/__init__.py @@ -0,0 +1,17 @@ +# -*- encoding=utf-8 -*- +""" +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-10-16 +# Description: check spec file +# ********************************************************************************** +""" \ No newline at end of file diff --git a/test/ac/acl/license/license_test_sample/no_spec/no_spec b/test/ac/acl/license/license_test_sample/no_spec/no_spec new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/ac/acl/license/license_test_sample/no_src/no_src b/test/ac/acl/license/license_test_sample/no_src/no_src new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/ac/acl/license/license_test_sample/pkgship/README.en.md b/test/ac/acl/license/license_test_sample/pkgship/README.en.md new file mode 100644 index 0000000000000000000000000000000000000000..ae5aff0dad8869a2b9b7b973d58a460cbc71015a --- /dev/null +++ b/test/ac/acl/license/license_test_sample/pkgship/README.en.md @@ -0,0 +1,36 @@ +# pkgship + +#### Description +a package depend query tool + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/test/ac/acl/license/license_test_sample/pkgship/README.md b/test/ac/acl/license/license_test_sample/pkgship/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b5a39bf91029b55ab201ba35a6b0957e3239519b --- /dev/null +++ b/test/ac/acl/license/license_test_sample/pkgship/README.md @@ -0,0 +1,176 @@ +[English](./README-en.md) | 简体中文 + +# pkgship + +## 介绍 +pkgship是一款管理OS软件包依赖关系,提供依赖和被依赖关系的完整图谱查询工具,pkgship提供软件包依赖,生命周期,补丁查询等功能。 +1. 软件包依赖:方便社区人员在新引入、软件包更新和删除的时候能方便的了解软件的影响范围。 +2. 生命周期管理:跟踪upstream软件包发布状态,方便维护人员了解当前软件状态,及时升级到合理的版本。 +3. 补丁查询:方便社区人员了解openEuler软件包的补丁情况,方便的提取补丁内容 + + +### 软件架构 +系统采用flask-restful开发,使用SQLAlchemy ORM查询框架,同时支持mysql和sqlite数据库,通过配置文件的形式进行更改 + + +安装教程 +--- +#### 方法一: 可以使用dnf挂载pkgship软件在所在repo源,直接下载安装pkgship及其依赖 + +``` +dnf install pkgship(版本号) +``` + +#### 方法二: 可以直接下载pkgship的rpm包后安装软件包 + +``` +rpm -ivh pkgship.rpm +``` +或者 +``` +dnf install pkgship-(版本号) +``` + +系统配置 +--- +系统的默认配置文件存放在 /etc/pkgship/packge.ini,请根据实际情况进行配置更改 + +``` +vim /etc/pkgship/package.ini +``` +创建初始化数据库的yaml配置文件: +conf.yaml 文件默认存放在 /etc/pkgship/ 路径下,pkgship会通过该配置读取要建立的数据库名称以及需要导入的sqlite文件。conf.yaml 示例如下: + +``` +- dbname:openEuler-20.03-LTS + src_db_file: +- /etc/pkgship/src.sqlite + bin_db_file: +- /etc/pkgship/bin.sqlite + status:enable + priority:1 +``` + +如需更改存放路径,请更改package.ini下的 init_conf_path 选项 + + +服务启动和停止 +--- +pkgship使用uWSGI web服务器 +``` +pkgshipd start + +pkgshipd stop +``` + +使用说明 +--- +#### 1. 数据库初始化 +``` +pkgship init +``` +#### 2. 单包查询 + +查询源码包(sourceName)在所有数据库中的信息 +``` +pkgship single sourceName +``` +查询当前包(sourceName)在指定数据库(dbName)中的信息 +``` +pkgship single sourceName -db dbName +``` +#### 3. 查询所有包 +查询所有数据库下包含的所有包的信息 +``` +pkgship list +``` +查询指定数据库(dbName)下的所有包的信息 +``` +pkgship list -db dbName +``` +#### 4. 安装依赖查询 +查询二进制包(binaryName)的安装依赖,按照默认优先级查询数据库 +``` +pkgship installdep binaryName +``` +在指定数据库(dbName)下查询二进制包(binaryName)的所有安装依赖 +按照先后顺序指定数据库查询的优先级 +``` +pkgship installdep binaryName -dbs dbName1 dbName2... +``` +#### 5. 编译依赖查询 +查询源码包(sourceName)的所有编译依赖,按照默认优先级查询数据库 +``` +pkgship builddep sourceName +``` +在指定数据库(dbName)下查询源码包(sourceName)的所有安装依赖 +按照先后顺序指定数据库查询的优先级 +``` +pkgship builddep sourceName -dbs dbName1 dbName2... +``` +#### 6. 自编译自安装依赖查询 +查询二进制包(binaryName)的安装和编译依赖,按照默认优先级查询数据库 +``` +pkgship selfbuild binaryName +``` +查询源码包(sourceName )的安装和编译依赖,按照默认优先级查询数据库 +``` +pkgship selfbuild sourceName -t source +``` +其他参数: + +-dbs 指定数据库优先级. +``` +示例:pkgship selfbuild binaryName -dbs dbName1 dbName2 +``` +-s 是否查询自编译依赖 +默认为0不查询自编译依赖,可以指定0或1(表示查询自编译) +``` +查询自编译示例:pkgship selfbuild sourceName -t source -s 1 +``` +-w 是否查询对应包的子包.默认为0,不查询对应子包,可以指定 0或1(表示查询对应子包) +``` +查询子包示例:pkgship selfbuild binaryName -w 1 +``` +#### 7. 被依赖查询 +查询源码包(sourceName)在某数据库(dbName)中被哪些包所依赖 +查询结果默认不包含对应二进制包的子包 +``` +pkgship bedepend sourceName -db dbName +``` +使查询结果包含二进制包的子包 加入参数 -w +``` +pkgship bedepend sourceName -db dbName -w 1 +``` +#### 8. 修改包信息记录 +变更数据库中(dbName)源码包(sourceName)的maintainer为Newmaintainer +``` +pkgship updatepkg sourceName db dbName -m Newmaintainer +``` +变更数据库中(dbName)源码包(sourceName)的maintainlevel为Newmaintainlevel,值在1~4之间 +``` +pkgship updatepkg sourceName db dbName -l Newmaintainlevel +``` +同时变更数据库中(dbName)源码包(sourceName)的maintainer 为Newmaintainer和变更maintainlevel为Newmaintainlevel +``` +pkgship updatepkg sourceName db dbName -m Newmaintainer -l Newmaintainlevel +``` +#### 9. 删除数据库 +删除指定数据库(dbName) +``` +pkgship rm db dbName +``` + +参与贡献 +--- +我们非常欢迎新贡献者加入到项目中来,也非常高兴能为新加入贡献者提供指导和帮助。在您贡献代码前,需要先签署[CLA](https://openeuler.org/en/cla.html)。 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +### 会议记录 +1. 2020.5.18:https://etherpad.openeuler.org/p/aHIX4005bTY1OHtOd_Zc + diff --git a/test/ac/acl/license/license_test_sample/pkgship/pkgship-1.1.0.tar.gz b/test/ac/acl/license/license_test_sample/pkgship/pkgship-1.1.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..9e45007af4b886171379b56d7a74feb9acce0481 Binary files /dev/null and b/test/ac/acl/license/license_test_sample/pkgship/pkgship-1.1.0.tar.gz differ diff --git a/test/ac/acl/license/license_test_sample/pkgship/pkgship.spec b/test/ac/acl/license/license_test_sample/pkgship/pkgship.spec new file mode 100644 index 0000000000000000000000000000000000000000..0abe1da5bfa7ef80919984e30bd89295a4a86e24 --- /dev/null +++ b/test/ac/acl/license/license_test_sample/pkgship/pkgship.spec @@ -0,0 +1,164 @@ +Name: pkgship +Version: 1.1.0 +Release: 14 +Summary: Pkgship implements rpm package dependence ,maintainer, patch query and so no. +License: Mulan 2.0 +URL: https://gitee.com/openeuler/openEuler-Advisor +Source0: https://gitee.com/openeuler/openEuler-Advisor/pkgship-%{version}.tar.gz + +# Modify the query logic of package information, reduce redundant queries and align dnf query results, +# extract multiplexing functions, add corresponding docString, and clear pylint +Patch0: 0001-solve-installation-dependency-query-error.patch + +# Fix the problem of continuous spaces in message information in log records +Patch1: 0002-fix-the-problem-of-continuous-spaces.patch + +# When initializing logging, modify the incoming class object to an instance of the class, +# ensure the execution of internal functions,and read configuration file content +Patch2: 0003-fix-log_level-configuration-item-not-work.patch + +# Fix the error when executing query commands +Patch3: 0004-fix-the-error-when-executing-query-commands.patch + +# Add the judgment of whether the subpack_name attribute exists, fix the code indentation problem, +# and reduce the judgment branch of the old code. +Patch4: 0005-fix-the-error-when-source-package-has-no-sub-packages.patch + +# Solve the problem of data duplication, increase the maximum queue length judgment, +# and avoid occupying too much memory +Patch5: 0006-fix-memory_caused-service-crash-and-data-duplication-issue.patch + +# Fix the problem of function parameters +Patch6: 0007-correct-the-parameter-transfer-method-and-change-the-status-recording-method.patch + +# Fix the selfbuild error message +Patch7: 0008-fix-selfbuild-error-message.patch + +# Optimize-log-records-when-obtaining-issue-content +Patch8: 0009-optimize-log-records-when-obtaining-issue-content.patch +BuildArch: noarch + +BuildRequires: python3-flask-restful python3-flask python3 python3-pyyaml python3-sqlalchemy +BuildRequires: python3-prettytable python3-requests python3-flask-session python3-flask-script python3-marshmallow +BuildRequires: python3-Flask-APScheduler python3-pandas python3-retrying python3-xlrd python3-XlsxWriter +BuildRequires: python3-concurrent-log-handler +Requires: python3-pip python3-flask-restful python3-flask python3 python3-pyyaml +Requires: python3-sqlalchemy python3-prettytable python3-requests python3-concurrent-log-handler +Requires: python3-flask-session python3-flask-script python3-marshmallow python3-uWSGI +Requires: python3-pandas python3-dateutil python3-XlsxWriter python3-xlrd python3-Flask-APScheduler python3-retrying + +%description +Pkgship implements rpm package dependence ,maintainer, patch query and so no. + +%prep +%autosetup -n pkgship-%{version} -p1 + +%build +%py3_build + +%install +%py3_install + + +%check +# The apscheduler cannot catch the local time, so a time zone must be assigned before running the test case. +export TZ=Asia/Shanghai +# change log_path to solve default log_path permission denied problem +log_path=`pwd`/tmp/ +sed -i "/\[LOG\]/a\log_path=$log_path" test/common_files/package.ini +%{__python3} -m unittest test/init_test.py +%{__python3} -m unittest test/read_test.py +%{__python3} -m unittest test/write_test.py +rm -rf $log_path + +%post + +%postun + + +%files +%doc README.md +%{python3_sitelib}/* +%attr(0755,root,root) %config %{_sysconfdir}/pkgship/* +%attr(0755,root,root) %{_bindir}/pkgshipd +%attr(0755,root,root) %{_bindir}/pkgship + +%changelog +* Tue Oct 13 2020 ZhangTao 1.1.0-14 +- correct-the-parameter-transfer-method-and-change-the-status-recording-method. + +* Fri Sep 25 2020 Cheng Shaowei 1.1.0-13 +- Optimize-log-records-when-obtaining-issue-content + +* Fri Sep 25 2020 Zhang Tao - 1.1.0-12 +- In the selfbuild scenario, add the error message that the software package cannot be found + +* Fri Sep 25 2020 Zhang Tao - 1.1.0-11 +- Fix the problem of function parameters + +* Thu Sep 24 2020 Yiru Wang - 1.1.0-10 +- rm queue_maxsize param from package.ini and this parameter is not customizable + +* Tue Sep 21 2020 Shenmei Tu - 1.0-0-9 +- Solve the problem of data duplication, increase the maximum queue length judgment, +- and avoid occupying too much memory + +* Mon Sep 21 2020 Shenmei Tu - 1.0-0-8 +- Add the judgment of whether the subpack_name attribute exists, fix the code indentation problem, +- and reduce the judgment branch of the old code. + +* Mon Sep 21 2020 Shenmei Tu - 1.0-0-7 +- fix the error when executing query commands + +* Mon Sep 21 2020 Shenmei Tu - 1.0-0-6 +- When initializing logging, modify the incoming class object to an instance of the class, +- ensure the execution of internal functions,and read configuration file content + +* Mon Sep 21 2020 Shenmei Tu - 1.0-0-5 +- Fix the problem of continuous spaces in message information in log records + +* Thu Sep 17 2020 Shenmei Tu - 1.0-0-4 +- Modify the query logic of package information, reduce redundant queries and align dnf query results, +- extract multiplexing functions, add corresponding docString, and clear pylint + +* Fri Sep 11 2020 Yiru Wang - 1.1.0-3 +- #I1UCM8, #I1UC8G: Modify some config files' permission issue; +- #I1TIYQ: Add concurrent-log-handler module to fix log resource conflict issue +- #I1TML0: Fix the matching relationship between source_rpm and src_name + +* Tue Sep 1 2020 Zhengtang Gong - 1.1.0-2 +- Delete the packaged form of pyinstaller and change the execution + of the command in the form of a single file as the input + +* Sat Aug 29 2020 Yiru Wang - 1.1.0-1 +- Add package management features: + RPM packages statically displayed in the version repository + RPM packages used time displayed for current version in the version repository + Issue management of packages in a version-management repository + +* Fri Aug 21 2020 Chengqiang Bao < baochengqiang1@huawei.com > - 1.0.0-7 +- Fixed a problem with command line initialization of the Filepath parameter where relative paths are not supported and paths are too long + +* Wed Aug 12 2020 Zhang Tao - 1.0.0-6 +- Fix the test content to adapt to the new data structure, add BuildRequires for running %check + +* Mon Aug 10 2020 Zhengtang Gong - 1.0-5 +- Command line supports calling remote services + +* Wed Aug 5 2020 Yiru Wang - 1.0-4 +- change Requires rpm pakcages' name to latest one + +* Mon Jul 13 2020 Yiru Wang - 1.0-3 +- run test cases while building + +* Sat Jul 4 2020 Yiru Wang - 1.0-2 +- cheange requires python3.7 to python3,add check pyinstaller file. + +* Tue Jun 30 2020 Yiru Wang - 1.0-1 +- add pkgshipd file + +* Thu Jun 11 2020 Feng Hu - 1.0-0 +- add macro to build cli bin when rpm install + +* Sat Jun 6 2020 Feng Hu - 1.0-0 +- init package diff --git a/test/ac/acl/license/license_test_sample/rubygem-mail/2.6.4.tar.gz b/test/ac/acl/license/license_test_sample/rubygem-mail/2.6.4.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3c7c19f7c87bcf156c34a394d514abe16ba5e9fe Binary files /dev/null and b/test/ac/acl/license/license_test_sample/rubygem-mail/2.6.4.tar.gz differ diff --git a/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4-Fix-deprecated-warnings-in-Ruby-2.4.0.patch b/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4-Fix-deprecated-warnings-in-Ruby-2.4.0.patch new file mode 100644 index 0000000000000000000000000000000000000000..01d3556a6f7966d99b539d2eb65c25d75f8cfc22 --- /dev/null +++ b/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4-Fix-deprecated-warnings-in-Ruby-2.4.0.patch @@ -0,0 +1,59 @@ +From e8fde9cf1d77ee7e465c12e809501df8d27e8451 Mon Sep 17 00:00:00 2001 +From: Koichi ITO +Date: Sun, 4 Dec 2016 12:33:06 +0800 +Subject: [PATCH] Fix deprecated warnings in Ruby 2.4.0+ + +--- + lib/mail/attachments_list.rb | 2 +- + lib/mail/multibyte/chars.rb | 4 ++-- + lib/mail/network/retriever_methods/test_retriever.rb | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/lib/mail/attachments_list.rb b/lib/mail/attachments_list.rb +index bb34a85..14fe31c 100644 +--- a/lib/mail/attachments_list.rb ++++ b/lib/mail/attachments_list.rb +@@ -30,7 +30,7 @@ module Mail + # mail.attachments['test.png'].filename #=> 'test.png' + # mail.attachments[1].filename #=> 'test.jpg' + def [](index_value) +- if index_value.is_a?(Fixnum) ++ if index_value.is_a?(Integer) + self.fetch(index_value) + else + self.select { |a| a.filename == index_value }.first +diff --git a/lib/mail/multibyte/chars.rb b/lib/mail/multibyte/chars.rb +index bb39897..2e431ca 100644 +--- a/lib/mail/multibyte/chars.rb ++++ b/lib/mail/multibyte/chars.rb +@@ -269,12 +269,12 @@ module Mail #:nodoc: + @wrapped_string[*args] = replace_by + else + result = Unicode.u_unpack(@wrapped_string) +- if args[0].is_a?(Fixnum) ++ if args[0].is_a?(Integer) + raise IndexError, "index #{args[0]} out of string" if args[0] >= result.length + min = args[0] + max = args[1].nil? ? min : (min + args[1] - 1) + range = Range.new(min, max) +- replace_by = [replace_by].pack('U') if replace_by.is_a?(Fixnum) ++ replace_by = [replace_by].pack('U') if replace_by.is_a?(Integer) + elsif args.first.is_a?(Range) + raise RangeError, "#{args[0]} out of range" if args[0].min >= result.length + range = args[0] +diff --git a/lib/mail/network/retriever_methods/test_retriever.rb b/lib/mail/network/retriever_methods/test_retriever.rb +index 9bb3e1a..dfbc909 100644 +--- a/lib/mail/network/retriever_methods/test_retriever.rb ++++ b/lib/mail/network/retriever_methods/test_retriever.rb +@@ -25,7 +25,7 @@ module Mail + emails_index.reverse! if options[:what] == :last + emails_index = case count = options[:count] + when :all then emails_index +- when Fixnum then emails_index[0, count] ++ when Integer then emails_index[0, count] + else + raise 'Invalid count option value: ' + count.inspect + end +-- +2.11.0 + diff --git a/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4-fix-new-warning-in-ruby-2.4.patch b/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4-fix-new-warning-in-ruby-2.4.patch new file mode 100644 index 0000000000000000000000000000000000000000..af455602f552ad3069f29a7d32e64feea9dc5b1d --- /dev/null +++ b/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4-fix-new-warning-in-ruby-2.4.patch @@ -0,0 +1,38 @@ +From 48cb6db25b31eebe7bdd330d812c52d3c93aa328 Mon Sep 17 00:00:00 2001 +From: "yuuji.yaginuma" +Date: Tue, 13 Dec 2016 07:50:42 +0900 +Subject: [PATCH] fix new warning in ruby 2.4 + +This fixes the following warning. + +``` +/home/travis/build/mikel/mail/lib/mail/fields/common/address_container.rb:11: warning: parentheses after method name is interpreted as +/home/travis/build/mikel/mail/lib/mail/fields/common/address_container.rb:11: warning: an argument list, not a decomposed argument +``` + +Ref: https://github.com/ruby/ruby/commit/65e27c8b138d6959608658ffce2fa761842b8d24 +--- + lib/mail/fields/common/address_container.rb | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/mail/fields/common/address_container.rb b/lib/mail/fields/common/address_container.rb +index f4a5aec..48c1286 100644 +--- a/lib/mail/fields/common/address_container.rb ++++ b/lib/mail/fields/common/address_container.rb +@@ -8,10 +8,10 @@ module Mail + super(list) + end + +- def << (address) ++ def <<(address) + @field << address + end + + end + +-end +\ No newline at end of file ++end +-- +2.11.0 + diff --git a/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4.gem b/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4.gem new file mode 100644 index 0000000000000000000000000000000000000000..4fa553a1f40c3cccb1614b4a9b980cb907d3b860 Binary files /dev/null and b/test/ac/acl/license/license_test_sample/rubygem-mail/mail-2.6.4.gem differ diff --git a/test/ac/acl/license/license_test_sample/rubygem-mail/rubygem-mail.spec b/test/ac/acl/license/license_test_sample/rubygem-mail/rubygem-mail.spec new file mode 100644 index 0000000000000000000000000000000000000000..750602f02adb2acd78c5f8d40fb18b9b457d0575 --- /dev/null +++ b/test/ac/acl/license/license_test_sample/rubygem-mail/rubygem-mail.spec @@ -0,0 +1,71 @@ +%global gem_name mail +Name: rubygem-%{gem_name} +Version: 2.6.4 +Release: 2 +Summary: Mail provides a nice Ruby DSL for making, sending and reading emails +License: MIT +URL: https://github.com/mikel/mail +Source0: https://rubygems.org/gems/%{gem_name}-%{version}.gem +Source1: https://github.com/mikel/mail/archive/%{version}.tar.gz +# Fix Ruby 2.4 compatibility. +# https://github.com/mikel/mail/commit/e8fde9cf1d77ee7e465c12e809501df8d27e8451 +Patch0: mail-2.6.4-Fix-deprecated-warnings-in-Ruby-2.4.0.patch +# https://github.com/mikel/mail/commit/48cb6db25b31eebe7bdd330d812c52d3c93aa328 +Patch1: mail-2.6.4-fix-new-warning-in-ruby-2.4.patch +BuildRequires: ruby(release) rubygems-devel ruby rubygem(mime-types) >= 1.16 rubygem(rspec) +BuildArch: noarch +%description +A really Ruby Mail handler. + +%package doc +Summary: Documentation for %{name} +Requires: %{name} = %{version}-%{release} +BuildArch: noarch +%description doc +Documentation for %{name}. + +%prep +%setup -q -c -T +ln -s %{_builddir}/%{gem_name}-%{version}/spec ../spec +%gem_install -n %{SOURCE0} +pushd .%{gem_instdir} +%patch0 -p1 +%patch1 -p1 +popd + +%build + +%install +mkdir -p %{buildroot}%{gem_dir} +cp -a .%{gem_dir}/* \ + %{buildroot}%{gem_dir}/ + +%check +pushd .%{gem_instdir} +tar xzvf %{SOURCE1} +rspec spec +popd + +%files +%dir %{gem_instdir} +%license %{gem_instdir}/MIT-LICENSE +%{gem_libdir} +%exclude %{gem_cache} +%{gem_spec} + +%files doc +%doc %{gem_docdir} +%doc %{gem_instdir}/CHANGELOG.rdoc +%doc %{gem_instdir}/CONTRIBUTING.md +%doc %{gem_instdir}/Dependencies.txt +%{gem_instdir}/Gemfile* +%doc %{gem_instdir}/README.md +%{gem_instdir}/Rakefile +%doc %{gem_instdir}/TODO.rdoc + +%changelog +* Tue Sep 8 2020 geyanan - 2.6.4-2 +- fix build fail + +* Wed Aug 19 2020 geyanan - 2.6.4-1 +- package init diff --git a/test/ac/acl/license/license_test_sample/rubygem-mail/rubygem-mail.yaml b/test/ac/acl/license/license_test_sample/rubygem-mail/rubygem-mail.yaml new file mode 100644 index 0000000000000000000000000000000000000000..98f733e147e70f49f88c832934a60cef477b5fdf --- /dev/null +++ b/test/ac/acl/license/license_test_sample/rubygem-mail/rubygem-mail.yaml @@ -0,0 +1,4 @@ +version_control: github +src_repo: mikel/mail +tag_prefix: "" +seperator: "." diff --git a/test/ac/acl/license/license_test_sample/spec_fail/spec_fail.spec b/test/ac/acl/license/license_test_sample/spec_fail/spec_fail.spec new file mode 100644 index 0000000000000000000000000000000000000000..80b9b23d87dd793ead6056a013fdac2a522635a4 --- /dev/null +++ b/test/ac/acl/license/license_test_sample/spec_fail/spec_fail.spec @@ -0,0 +1,37 @@ +Name: spec_fail +Version: 1.1.0 +Release: 1 +Summary: test case for spec license error. +License: Mulan 2.0 and ADSL +URL: https://gitee.com/openeuler/openEuler-Advisor +Source0: https://gitee.com/openeuler/openEuler-Advisor/pkgship-%{version}.tar.gz + +%description +test case for spec license error. + +%prep +%autosetup + +%build +%py3_build + +%install +%py3_install + +%check + +%post + +%postun + + +%files +%doc README.md +%{python3_sitelib}/* +%attr(0755,root,root) %config %{_sysconfdir}/pkgship/* +%attr(0755,root,root) %{_bindir}/pkgshipd +%attr(0755,root,root) %{_bindir}/pkgship + +%changelog +* Mon Oct 19 2020 xxx - 1.0-0 +- init package diff --git a/test/ac/acl/license/license_test_sample/spec_src_diff/spec_src_diff b/test/ac/acl/license/license_test_sample/spec_src_diff/spec_src_diff new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/ac/acl/license/license_test_sample/spec_src_same/spec_src_same b/test/ac/acl/license/license_test_sample/spec_src_same/spec_src_same new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/ac/acl/license/license_test_sample/src_fail/src_fail b/test/ac/acl/license/license_test_sample/src_fail/src_fail new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/ac/acl/license/license_test_sample/src_success/src_success b/test/ac/acl/license/license_test_sample/src_success/src_success new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/ac/acl/license/test_check_license.py b/test/ac/acl/license/test_check_license.py new file mode 100644 index 0000000000000000000000000000000000000000..22431ef7cff5ab238c3b1046dcfd51c85dfdc99f --- /dev/null +++ b/test/ac/acl/license/test_check_license.py @@ -0,0 +1,133 @@ +# -*- encoding=utf-8 -*- +""" +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: +# Create: 2020-10-16 +# Description: check spec file +# ********************************************************************************** +""" + +import unittest +import mock +import sys +import os +import types +import logging.config +import logging +import shutil + +from src.ac.framework.ac_result import FAILED, WARNING, SUCCESS +from src.ac.acl.package_license.check_license import CheckLicense + +logging.getLogger('test_logger') + +class TestCheckPkgLicense(unittest.TestCase): + DIR_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), + "license_test_sample") + + TEST_SAMPLE_DIR = { + "no_spec": "no_spec", + "spec_success": "pkgship", + "spec_fail": "spec_fail", + "no_src": "no_src", + "src_success": "rubygem-mail", + "src_fail": "pkgship", + "spec_src_same": "rubygem-mail", + "spec_src_diff": "pkgship" + } + + def bind_func(self, check): + def get_work_tar_dir(self): + return self._work_tar_dir + def load_license_config(self): + self._pkg_license.load_config() + def decompress(self): + self._gr.decompress_all() + check.get_work_tar_dir = types.MethodType(get_work_tar_dir, check, CheckLicense) + check.load_license_config = types.MethodType(load_license_config, check, CheckLicense) + check.decompress = types.MethodType(decompress, check, CheckLicense) + + def _test_check_license_in_spec(self, dir_key, predict): + os.chdir(os.path.join(self.DIR_PATH, + self.TEST_SAMPLE_DIR[dir_key])) + cl = CheckLicense(self.DIR_PATH, + self.TEST_SAMPLE_DIR[dir_key]) + self.bind_func(cl) + cl.load_license_config() + self.assertEqual(cl.check_license_in_spec(), predict) + + def test_check_license_in_spec_none(self): + self._test_check_license_in_spec("no_spec", WARNING) + + def test_check_license_in_spec_succeed(self): + self._test_check_license_in_spec("spec_success", SUCCESS) + + def test_check_license_in_spec_failed(self): + self._test_check_license_in_spec("spec_fail", WARNING) + + def _test_check_license_in_src(self, dir_key, predict): + os.chdir(os.path.join(self.DIR_PATH, + self.TEST_SAMPLE_DIR[dir_key])) + cl = CheckLicense(self.DIR_PATH, + self.TEST_SAMPLE_DIR[dir_key]) + self.bind_func(cl) + _ = not os.path.exists(cl.get_work_tar_dir()) and os.mkdir(cl.get_work_tar_dir()) + try: + cl.decompress() + cl.load_license_config() + self.assertEqual(cl.check_license_in_src(), predict) + finally: + shutil.rmtree(cl.get_work_tar_dir()) + + def test_check_license_none(self): + self._test_check_license_in_src("no_src", WARNING) + + def test_check_license_in_src_succeed(self): + self._test_check_license_in_src("src_success", SUCCESS) + + def test_check_license_in_src_failed(self): + self._test_check_license_in_src("src_fail", WARNING) + + def _test_check_license_same(self, dir_key, predict): + os.chdir(os.path.join(self.DIR_PATH, + self.TEST_SAMPLE_DIR[dir_key])) + cl = CheckLicense(self.DIR_PATH, + self.TEST_SAMPLE_DIR[dir_key]) + self.bind_func(cl) + _ = not os.path.exists(cl.get_work_tar_dir()) and os.mkdir(cl.get_work_tar_dir()) + try: + cl.decompress() + cl.load_license_config() + cl.check_license_in_spec() + cl.check_license_in_src() + self.assertEqual(cl.check_license_is_same(), predict) + finally: + shutil.rmtree(cl.get_work_tar_dir()) + + def test_check_license_same_succeed(self): + self._test_check_license_same("spec_src_same", SUCCESS) + + def test_cehck_license_same_failed(self): + self._test_check_license_same("spec_src_diff", WARNING) + + +if __name__ == "__main__": + work_dir = os.getcwd() + _ = not os.path.exists("log") and os.mkdir("log") + logger_conf_path = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../../../src/conf/logger.conf")) + logging.config.fileConfig(logger_conf_path) + logger = logging.getLogger("test_logger") + # Test Package License + suite = unittest.makeSuite(TestCheckPkgLicense) + unittest.TextTestRunner().run(suite) + os.chdir(work_dir) + shutil.rmtree("log") \ No newline at end of file diff --git a/test/ac/acl/package_yaml/__init__.py b/test/ac/acl/package_yaml/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ed5bdad435b94b1475a582e9f6602dd020179de1 --- /dev/null +++ b/test/ac/acl/package_yaml/__init__.py @@ -0,0 +1,17 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-21 +# Description: +# ***********************************************************************************/ +""" \ No newline at end of file diff --git a/test/ac/acl/package_yaml/fields_test_sample/missing.yaml b/test/ac/acl/package_yaml/fields_test_sample/missing.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7bc47b74eb3f6e60296bc16169369c7172f90c36 --- /dev/null +++ b/test/ac/acl/package_yaml/fields_test_sample/missing.yaml @@ -0,0 +1,2 @@ +src_repo: a/b +tag_prefix: NA \ No newline at end of file diff --git a/test/ac/acl/package_yaml/fields_test_sample/standard.yaml b/test/ac/acl/package_yaml/fields_test_sample/standard.yaml new file mode 100644 index 0000000000000000000000000000000000000000..10fe26eb145880d7fb785e919924d09145839248 --- /dev/null +++ b/test/ac/acl/package_yaml/fields_test_sample/standard.yaml @@ -0,0 +1,4 @@ +version_control: testvc +src_repo: src/repo +tag_prefix: "v" +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/git_test/git_test.spec b/test/ac/acl/package_yaml/repo_test_sample/git_test/git_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..9aebd3154f4fbaeae9044dd72c2a87ffeb5ce72d --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/git_test/git_test.spec @@ -0,0 +1,84 @@ +%global __requires_exclude ^perl\\(Autom4te:: +%global __provides_exclude ^perl\\(Autom4te:: + +Name: autoconf +Version: 2.69 +Release: 30 +Summary: An extensible package to automatically configure software source code packages +License: GPLv2+ and GPLv3+ and GFDL +URL: https://www.gnu.org/software/%{name}/ +Source0: http://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Source1: config.site +Source2: autoconf-el.el + +# four patches backport from upstream to solve test suite failure +Patch1: autoscan-port-to-perl-5.17.patch +Patch2: Port-tests-to-Bash-5.patch +Patch3: tests-avoid-spurious-test-failure-with-libtool-2.4.3.patch +#fix the failure of test 38 autotools and whitespace in file names +Patch4: Fix-test-suite-with-modern-Perl.patch + +Patch9000: skip-one-test-at-line-1616-of-autotest.patch + +BuildArch: noarch + +BuildRequires: m4 emacs perl perl-generators help2man +Requires: m4 emacs-filesystem +Requires(post): info +Requires(preun):info + +%package_help + +%description +Autoconf is an extensible package of M4 macros that produce shell scripts to automatically +configure software source code packages. These scripts can adapt the packages to many kinds +of UNIX-like systems without manual user intervention. Autoconf creates a configuration script +for a package from a template file that lists the operating system features that the package +can use, in the form of M4 macro calls. + +%prep +%autosetup -n %{name}-%{version} -p1 + +%build +export EMACS=%{_bindir}/emacs +%configure --with-lispdir=%{_emacs_sitelispdir}/autoconf +%make_build + +%check +make %{?_smp_mflags} check + +%install +%make_install +install -p -D %{SOURCE1} %{buildroot}%{_datadir} +install -p -D %{SOURCE2} %{buildroot}%{_emacs_sitestartdir}/autoconf-el.el + +%post help +/sbin/install-info %{_infodir}/autoconf.info %{_infodir}/dir || : + +%preun help +if [ "$1" = 0 ]; then + /sbin/install-info --delete %{_infodir}/autoconf.info %{_infodir}/dir || : +fi + +%files +%doc ChangeLog README THANKS +%license COPYING* AUTHORS doc/autoconf.info +%{_bindir}/* +%{_datadir}/autoconf/ +%{_datadir}/config.site +%{_datadir}/emacs/site-lisp/* +%exclude %{_infodir}/standards* + +%files help +%doc NEWS TODO +%{_infodir}/autoconf.info* +%{_mandir}/man1/* +%exclude %{_infodir}/dir + + +%changelog +* Sat Jan 4 2020 openEuler Buildteam - 2.69-30 +- Strengthen sources and patches + +* Fri Oct 11 2019 openEuler Buildteam - 2.69-29 +- Package Init diff --git a/test/ac/acl/package_yaml/repo_test_sample/git_test/git_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/git_test/git_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..09b64c0d5f55ee466b0e9cfee1f94cb965cd8785 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/git_test/git_test.yaml @@ -0,0 +1,4 @@ +version_control: git +src_repo: https://git.savannah.gnu.org/git/autoconf.git +tag_prefix: "^v" +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/gitee_test/gitee_test.spec b/test/ac/acl/package_yaml/repo_test_sample/gitee_test/gitee_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..1da248dec3fff264c43608acd0bb8db6b77a4670 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/gitee_test/gitee_test.spec @@ -0,0 +1,263 @@ +%global _version 2.0.5 +%global _release 20200923.100811.git275398ce +%global is_systemd 1 + +Name: iSulad +Version: %{_version} +Release: %{_release} +Summary: Lightweight Container Runtime Daemon +License: Mulan PSL v2 +URL: https://gitee.com/openeuler/iSulad +Source: https://gitee.com/openeuler/iSulad/repository/archive/v%{version}.tar.gz +BuildRoot: {_tmppath}/iSulad-%{version} +ExclusiveArch: x86_64 aarch64 + +Patch6000: 0000-config-remove-unused-config.patch +Patch6001: 0001-fix-modify-quota-log-level-to-warning.patch +Patch6002: 0002-fix-memory-leak.patch +Patch6003: 0003-fix-security-opt-parsing-access-out-of-bounds.patch +Patch6004: 0004-fix-delete-rootfs-dir-when-rootfs-load-failed.patch +Patch6005: 0005-fix-code-review.patch +Patch6006: 0006-fix-pull-failure-caused-by-link-conflict.patch +Patch6007: 0007-image-clear-memory-if-failed.patch +Patch6008: 0008-fix-layer-remain-caused-by-hold-flag-not-clean.patch +Patch6009: 0009-fix-coredump-when-pull-image-with-lock-driver-image-.patch +Patch6010: 0010-fix-bad-formatting-placeholder-in-http-parse-module.patch +Patch6011: 0011-iSulad-fix-memory-leak.patch +Patch6012: 0012-fix-coredump-when-load-image-with-uid.patch + +%ifarch x86_64 aarch64 +Provides: libhttpclient.so()(64bit) +Provides: libisula.so()(64bit) +Provides: libisulad_img.so()(64bit) +%endif + +%if 0%{?is_systemd} +# Systemd 230 and up no longer have libsystemd-journal +BuildRequires: pkgconfig(systemd) +Requires: systemd-units +%else +Requires(post): chkconfig +Requires(preun): chkconfig +# This is for /sbin/service +Requires(preun): initscripts +%endif + +BuildRequires: cmake gcc-c++ lxc lxc-devel lcr-devel yajl-devel clibcni-devel +BuildRequires: grpc grpc-plugins grpc-devel protobuf-devel +BuildRequires: libcurl libcurl-devel sqlite-devel libarchive-devel device-mapper-devel +BuildRequires: http-parser-devel +BuildRequires: libseccomp-devel libcap-devel libselinux-devel libwebsockets libwebsockets-devel +BuildRequires: systemd-devel git + +Requires: lcr lxc clibcni +Requires: grpc protobuf +Requires: libcurl +Requires: sqlite http-parser libseccomp +Requires: libcap libselinux libwebsockets libarchive device-mapper +Requires: systemd + +%description +This is a umbrella project for gRPC-services based Lightweight Container +Runtime Daemon, written by C. + +%prep +%autosetup -n %{name} -Sgit -p1 + +%build +mkdir -p build +cd build +%cmake -DDEBUG=ON -DLIB_INSTALL_DIR=%{_libdir} -DCMAKE_INSTALL_PREFIX=/usr ../ +%make_build + +%install +rm -rf %{buildroot} +cd build +install -d $RPM_BUILD_ROOT/%{_libdir} +install -m 0644 ./src/libisula.so %{buildroot}/%{_libdir}/libisula.so +install -m 0644 ./src/utils/http/libhttpclient.so %{buildroot}/%{_libdir}/libhttpclient.so +install -m 0644 ./src/daemon/modules/image/libisulad_img.so %{buildroot}/%{_libdir}/libisulad_img.so +chmod +x %{buildroot}/%{_libdir}/libisula.so +chmod +x %{buildroot}/%{_libdir}/libhttpclient.so +chmod +x %{buildroot}/%{_libdir}/libisulad_img.so + +install -d $RPM_BUILD_ROOT/%{_libdir}/pkgconfig +install -m 0640 ./conf/isulad.pc %{buildroot}/%{_libdir}/pkgconfig/isulad.pc + +install -d $RPM_BUILD_ROOT/%{_bindir} +install -m 0755 ./src/isula %{buildroot}/%{_bindir}/isula +install -m 0755 ./src/isulad-shim %{buildroot}/%{_bindir}/isulad-shim +install -m 0755 ./src/isulad %{buildroot}/%{_bindir}/isulad +chrpath -d ./src/isula +chrpath -d ./src/isulad-shim +chrpath -d ./src/isulad + +install -d $RPM_BUILD_ROOT/%{_includedir}/isulad +install -m 0644 ../src/client/libisula.h %{buildroot}/%{_includedir}/isulad/libisula.h +install -m 0644 ../src/client/connect/isula_connect.h %{buildroot}/%{_includedir}/isulad/isula_connect.h +install -m 0644 ../src/utils/cutils/utils_timestamp.h %{buildroot}/%{_includedir}/isulad/utils_timestamp.h +install -m 0644 ../src/utils/cutils/error.h %{buildroot}/%{_includedir}/isulad/error.h +install -m 0644 ../src/daemon/modules/runtime/engines/engine.h %{buildroot}/%{_includedir}/isulad/engine.h +install -m 0644 ../src/daemon/modules/api/image_api.h %{buildroot}/%{_includedir}/isulad/image_api.h + +install -d $RPM_BUILD_ROOT/%{_sysconfdir}/isulad +install -m 0640 ../src/contrib/config/daemon.json %{buildroot}/%{_sysconfdir}/isulad/daemon.json +install -m 0640 ../src/contrib/config/seccomp_default.json %{buildroot}/%{_sysconfdir}/isulad/seccomp_default.json + +install -d $RPM_BUILD_ROOT/%{_sysconfdir}/default/isulad +install -m 0640 ../src/contrib/config/config.json %{buildroot}/%{_sysconfdir}/default/isulad/config.json +install -m 0640 ../src/contrib/config/systemcontainer_config.json %{buildroot}/%{_sysconfdir}/default/isulad/systemcontainer_config.json +install -m 0550 ../src/contrib/sysmonitor/isulad-check.sh %{buildroot}/%{_sysconfdir}/default/isulad/isulad-check.sh + +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sysmonitor/process +cp ../src/contrib/sysmonitor/isulad-monit $RPM_BUILD_ROOT/etc/sysmonitor/process + +install -d $RPM_BUILD_ROOT/%{_sysconfdir}/default/isulad/hooks +install -m 0640 ../src/contrib/config/hooks/default.json %{buildroot}/%{_sysconfdir}/default/isulad/hooks/default.json + +install -d $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig +install -p -m 0640 ../src/contrib/config/iSulad.sysconfig $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/iSulad + +%if 0%{?is_systemd} +install -d $RPM_BUILD_ROOT/%{_unitdir} +install -p -m 0640 ../src/contrib/init/isulad.service $RPM_BUILD_ROOT/%{_unitdir}/isulad.service +%else +install -d $RPM_BUILD_ROOT/%{_initddir} +install -p -m 0640 ../src/contrib/init/isulad.init $RPM_BUILD_ROOT/%{_initddir}/isulad.init +%endif + +%clean +rm -rf %{buildroot} + +%pre +# support update from lcrd to isulad, will remove in next version +if [ "$1" = "2" ]; then +%if 0%{?is_systemd} +systemctl stop lcrd +systemctl disable lcrd +if [ -e %{_sysconfdir}/isulad/daemon.json ];then + sed -i 's#/etc/default/lcrd/hooks#/etc/default/isulad/hooks#g' %{_sysconfdir}/isulad/daemon.json +fi +%else +/sbin/chkconfig --del lcrd +%endif +fi + +%post +if ! getent group isulad > /dev/null; then + groupadd --system isulad +fi + +if [ "$1" = "1" ]; then +%if 0%{?is_systemd} +systemctl enable isulad +systemctl start isulad +%else +/sbin/chkconfig --add isulad +%endif +elif [ "$1" = "2" ]; then +%if 0%{?is_systemd} +# support update from lcrd to isulad, will remove in next version +if [ -e %{_unitdir}/lcrd.service.rpmsave ]; then + mv %{_unitdir}/lcrd.service.rpmsave %{_unitdir}/isulad.service + sed -i 's/lcrd/isulad/g' %{_unitdir}/isulad.service +fi +systemctl status isulad | grep 'Active:' | grep 'running' +if [ $? -eq 0 ]; then + systemctl restart isulad +else + systemctl start isulad +fi +%else +/sbin/service isulad status | grep 'Active:' | grep 'running' +if [ $? -eq 0 ]; then + /sbin/service isulad restart +fi +%endif +fi + +if ! getent group isulad > /dev/null; then + groupadd --system isulad +fi + +%preun +%if 0%{?is_systemd} +%systemd_preun isulad +%else +if [ $1 -eq 0 ] ; then + /sbin/service isulad stop >/dev/null 2>&1 + /sbin/chkconfig --del isulad +fi +%endif + +%postun +%if 0%{?is_systemd} +%systemd_postun_with_restart isulad +%else +if [ "$1" -ge "1" ] ; then + /sbin/service isulad condrestart >/dev/null 2>&1 || : +fi +%endif + +%files +%attr(0600,root,root) %{_sysconfdir}/sysmonitor/process/isulad-monit +%attr(0550,root,root) %{_sysconfdir}/default/isulad/isulad-check.sh +%defattr(0640,root,root,0750) +%{_sysconfdir}/isulad +%{_sysconfdir}/isulad/* +%{_sysconfdir}/default/* +%defattr(-,root,root,-) +%if 0%{?is_systemd} +%{_unitdir}/isulad.service +%attr(0640,root,root) %{_unitdir}/isulad.service +%else +%{_initddir}/isulad.init +%attr(0640,root,root) %{_initddir}/isulad.init +%endif +%{_includedir}/isulad/* +%attr(0755,root,root) %{_libdir}/pkgconfig +%attr(0640,root,root) %{_libdir}/pkgconfig/isulad.pc +%defattr(0550,root,root,0750) +%{_bindir}/* +%{_libdir}/* +%attr(0640,root,root) %{_sysconfdir}/sysconfig/iSulad +%attr(0640,root,root) %{_sysconfdir}/isulad/daemon.json + +%config(noreplace,missingok) %{_sysconfdir}/sysconfig/iSulad +%config(noreplace,missingok) %{_sysconfdir}/isulad/daemon.json +%if 0%{?is_systemd} +%config(noreplace,missingok) %{_unitdir}/isulad.service +%else +%config(noreplace,missingok) %{_initddir}/isulad.init +%endif + +%changelog ++* Fri Sep 23 2020 - 2.0.5-20200923.100811.git275398ce ++- Type:bugfix ++- ID:NA ++- SUG:NA ++- DESC: fix some memory bugs + ++* Fri Sep 18 2020 - 2.0.5-20200918.112827.git9aea9b75 ++- Type:bugfix ++- ID:NA ++- SUG:NA ++- DESC: modify log level to warn + ++* Mon Sep 14 2020 - 2.0.5-20200914.172527.gitae86920a ++- Type:bugfix ++- ID:NA ++- SUG:NA ++- DESC: remove unused config + +* Tue Sep 10 2020 - 2.0.5-20200910.144345.git71b1055b +- Type:enhancement +- ID:NA +- SUG:NA +- DESC: add chrpath + +* Fri Sep 04 2020 zhangxiaoyu - 2.0.5-20200904.114315.gitff1761c3 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC: upgrade from v2.0.3 to v2.0.5 diff --git a/test/ac/acl/package_yaml/repo_test_sample/gitee_test/gitee_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/gitee_test/gitee_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b2484d31d5572364b494dab109bf5223977aa591 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/gitee_test/gitee_test.yaml @@ -0,0 +1,4 @@ +version_control: gitee +src_repo: openEuler/iSulad +tag_prefix: "v" +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/github_test/github_test.spec b/test/ac/acl/package_yaml/repo_test_sample/github_test/github_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..e02588d51731ae4608c690a498fbcaa55a5b121a --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/github_test/github_test.spec @@ -0,0 +1,107 @@ +%global _name pyinotify +%global _description Pyinotify is a Python module for monitoring filesystems changes. \ +Pyinotify relies on a Linux Kernel feature (merged in kernel 2.6.13) called inotify. \ +inotify is an event-driven notifier, its notifications are exported from kernel space \ +to user space through three system calls. pyinotify binds these system calls and provides \ +an implementation on top of them offering a generic and abstract way to manipulate those \ +functionalities. + +Name: python-inotify +Version: 0.9.6 +Release: 16 +Summary: A Python module for monitoring filesystems changes +License: MIT +URL: https://github.com/seb-m/pyinotify +Source0: https://github.com/seb-m/pyinotify/archive/%{version}.tar.gz#/%{_name}-%{version}.tar.gz + +Patch0: pyinotify-0.9.6-epoint.patch +BuildArch: noarch +BuildRequires: gmp-devel + +%description +%{_description} + +%package -n python2-inotify +Summary: python2 edition of %{name} + +BuildRequires: python2-devel + +Provides: python2-inotify-examples + +Obsoletes: python2-inotify-examples + +%{?python_provide:%python_provide python2-inotify} + +%description -n python2-inotify +This package is the python2 edition of %{name}. + +%package -n python3-inotify +Summary: python3 edition of %{name} + +BuildRequires: python3-devel + +%{?python_provide:%python_provide python3-inotify} + +%description -n python3-inotify +This package is the python3 edition of %{name}. + +%package_help + +%prep +%autosetup -n %{_name}-%{version} -p1 +sed -i '1c#! %{__python2}' python2/pyinotify.py +sed -i '1c#! %{__python3}' python3/pyinotify.py +sed -i '1c#! %{__python2}' python2/examples/*py +sed -i '1c#! %{__python3}' python3/examples/*py +cp -a . $RPM_BUILD_DIR/python3-%{_name}-%{version} + +%build +%py2_build +cd $RPM_BUILD_DIR/python3-%{_name}-%{version} +%py3_build + +%install +cd $RPM_BUILD_DIR/python3-%{_name}-%{version} +%py3_install +mv %{buildroot}%{_bindir}/%{_name} %{buildroot}%{_bindir}/python3-%{_name} +cd - +%py2_install + +%files -n python2-inotify +%defattr(-,root,root) +%doc ACKS +%license COPYING +%doc python2/examples/* +%{_bindir}/%{_name} +%{python2_sitelib}/*.py* +%{python2_sitelib}/%{_name}*info/ + +%files -n python3-inotify +%defattr(-,root,root) +%doc ACKS +%license COPYING +%doc python3/examples/* +%{_bindir}/*3-%{_name} +%{python3_sitelib}/*.py* +%{python3_sitelib}/%{_name}*info/ +%{python3_sitelib}/__pycache__/*.pyc + +%files help +%defattr(-,root,root) +%doc README.md PKG-INFO + +%changelog +* Mon Dec 23 2019 openEuler Buildteam - 0.9.6-16 +- Type:NA +- ID:NA +- SUG:NA +- DESC:delete unneeded comments + +* Fri Sep 27 2019 shenyangyang - 0.9.6-15 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:move license file + +* Thu Sep 12 2019 openEuler Buildteam - 0.9.6-14 +- Package init diff --git a/test/ac/acl/package_yaml/repo_test_sample/github_test/github_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/github_test/github_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1f629d4e13c7f7b0510bee67f35e8a084f9db332 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/github_test/github_test.yaml @@ -0,0 +1,4 @@ +version_control: github +src_repo: seb-m/pyinotify +tag_prefix: "^" +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.spec b/test/ac/acl/package_yaml/repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..40078cbda92824ab7d5ca57505930346ef3b7648 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.spec @@ -0,0 +1,58 @@ +Name: gnome-dictionary +Version: 3.26.1 +Release: 4 +Summary: A dictionary application for GNOME +License: GPLv3+ and LGPLv2+ and GFDL +URL: https://wiki.gnome.org/Apps/Dictionary +Source0: https://download.gnome.org/sources/%{name}/3.26/%{name}-%{version}.tar.xz + +BuildRequires: desktop-file-utils docbook-style-xsl gettext itstool libappstream-glib libxslt +BuildRequires: meson pkgconfig(gobject-introspection-1.0) pkgconfig(gtk+-3.0) +Obsoletes: gnome-utils <= 1:3.3 gnome-utils-libs <= 1:3.3 gnome-utils-devel <= 1:3.3 +Obsoletes: gnome-dictionary-devel < 3.26.0 gnome-dictionary-libs < 3.26.0 + +%description +GNOME Dictionary is a simple, clean, elegant application to look up words in +online dictionaries using the DICT protocol. + +%package help +Summary: Help package for gnome-dictionary + +%description help +This package contains some man help files for gnome-dictionary. + +%prep +%autosetup -n %{name}-%{version} -p1 + +%build +%meson +%meson_build + +%install +%meson_install +%find_lang %{name} --with-gnome + +%check +appstream-util validate-relax --nonet %{buildroot}/%{_datadir}/appdata/*.appdata.xml +desktop-file-validate %{buildroot}/%{_datadir}/applications/*.desktop + +%postun +if [ $1 -eq 0 ]; then + glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null || : +fi + +%posttrans +glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null || : + +%files -f %{name}.lang +%doc COPYING* NEWS README.md +%{_bindir}/gnome-dictionary +%{_datadir}/* +%exclude %{_datadir}/man* + +%files help +%{_mandir}/man1/gnome-dictionary.1* + +%changelog +* Wed Dec 11 2019 lingsheng - 3.26.1-4 +- Package init diff --git a/test/ac/acl/package_yaml/repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..70537d024759da09f4eed7fc480ce859d4cf7c55 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.yaml @@ -0,0 +1,4 @@ +version_control: gitlab.gnome +src_repo: gnome-dictionary +tag_prefix: "^v" +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/gnu_ftp_test/gnu_ftp_test.spec b/test/ac/acl/package_yaml/repo_test_sample/gnu_ftp_test/gnu_ftp_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..80f2f0c41f29a5ec346725d521021e85cdf5dab2 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/gnu_ftp_test/gnu_ftp_test.spec @@ -0,0 +1,60 @@ +%bcond_with nls + +Name: help2man +Summary: Create simple man pages from --help output +Version: 1.47.11 +Release: 0 +License: GPLv3+ +URL: http://www.gnu.org/software/help2man +Source: ftp://ftp.gnu.org/gnu/help2man/help2man-%{version}.tar.xz + +%{!?with_nls:BuildArch: noarch} +BuildRequires: gcc perl-generators perl(Getopt::Long) perl(POSIX) perl(Text::ParseWords) perl(Text::Tabs) perl(strict) +%{?with_nls:BuildRequires: perl(Locale::gettext) /usr/bin/msgfmt} +%{?with_nls:BuildRequires: perl(Encode)} +%{?with_nls:BuildRequires: perl(I18N::Langinfo)} +Requires(post): /sbin/install-info +Requires(preun): /sbin/install-info + +%description +help2man is a tool for automatically generating simple manual pages from program output. + +%package_help + +%prep +%autosetup -n %{name}-%{version} + +%build +%configure --%{!?with_nls:disable}%{?with_nls:enable}-nls --libdir=%{_libdir}/help2man +%{make_build} + +%install +make install_l10n DESTDIR=$RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +%find_lang %name --with-man + +%post +%install_info %{_infodir}/help2man.info + +%preun +if [ $1 -eq 0 ]; then + %install_info_rm %{_infodir}/help2man.info +fi + +%files -f %name.lang +%defattr(-,root,root) +%doc README NEWS THANKS +%license COPYING +%{_bindir}/help2man +%{_infodir}/* +%if %{with nls} + %{_libdir}/help2man +%endif + +%files help +%defattr(-,root,root) +%{_mandir}/man1/* + +%changelog +* Thu Nov 07 2019 openEuler Buildtam - 1.47.11-0 +- Package Init diff --git a/test/ac/acl/package_yaml/repo_test_sample/gnu_ftp_test/gnu_ftp_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/gnu_ftp_test/gnu_ftp_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cdfc5e14ca8b6cab0344cc8b4ac42c44d74f715c --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/gnu_ftp_test/gnu_ftp_test.yaml @@ -0,0 +1,4 @@ +version_control: gnu-ftp +src_repo: help2man +tag_prefix: help2man-(.*).tar.xz(.sig)? +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/hg_test/hg_test.spec b/test/ac/acl/package_yaml/repo_test_sample/hg_test/hg_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..5158fb535f18a2e48a7ed7aea6a856e268f2d1b2 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/hg_test/hg_test.spec @@ -0,0 +1,381 @@ +%global _hardened_build 1 +%global nginx_user nginx + +%undefine _strict_symbol_defs_build + +%bcond_with geoip + +%global with_gperftools 1 + +%global with_mailcap_mimetypes 0 + +%global with_aio 1 + +Name: nginx +Epoch: 1 +Version: 1.18.0 +Release: 2 +Summary: A HTTP server, reverse proxy and mail proxy server +License: BSD +URL: http://nginx.org/ + +Source0: https://nginx.org/download/nginx-%{version}.tar.gz +Source10: nginx.service +Source11: nginx.logrotate +Source12: nginx.conf +Source13: nginx-upgrade +Source100: index.html +Source102: nginx-logo.png +Source103: 404.html +Source104: 50x.html +Source200: README.dynamic +Source210: UPGRADE-NOTES-1.6-to-1.10 + +Patch0: nginx-auto-cc-gcc.patch +Patch2: nginx-1.12.1-logs-perm.patch +BuildRequires: gcc openssl-devel pcre-devel zlib-devel systemd gperftools-devel +Requires: nginx-filesystem = %{epoch}:%{version}-%{release} openssl pcre +Requires: nginx-all-modules = %{epoch}:%{version}-%{release} +%if 0%{?with_mailcap_mimetypes} +Requires: nginx-mimetypes +%endif +Requires(pre): nginx-filesystem +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Provides: webserver +Recommends: logrotate + +%description +NGINX is a free, open-source, high-performance HTTP server and reverse proxy, +as well as an IMAP/POP3 proxy server. + +%package all-modules +Summary: Nginx modules +BuildArch: noarch + +%if %{with geoip} +Requires: nginx-mod-http-geoip = %{epoch}:%{version}-%{release} +%endif +Requires: nginx-mod-http-image-filter = %{epoch}:%{version}-%{release} +Requires: nginx-mod-http-perl = %{epoch}:%{version}-%{release} +Requires: nginx-mod-http-xslt-filter = %{epoch}:%{version}-%{release} +Requires: nginx-mod-mail = %{epoch}:%{version}-%{release} +Requires: nginx-mod-stream = %{epoch}:%{version}-%{release} + +%description all-modules +NGINX is a free, open-source, high-performance HTTP server and reverse proxy, +as well as an IMAP/POP3 proxy server. +This package is a meta package that installs all available Nginx modules. + +%package filesystem +Summary: Filesystem for the Nginx server +BuildArch: noarch +Requires(pre): shadow-utils + +%description filesystem +NGINX is a free, open-source, high-performance HTTP server and reverse proxy, +as well as an IMAP/POP3 proxy server. +The package contains the basic directory layout for the Nginx server. + +%if %{with geoip} +%package mod-http-geoip +Summary: HTTP geoip module for nginx +BuildRequires: GeoIP-devel +Requires: nginx GeoIP + +%description mod-http-geoip +The package is the Nginx HTTP geoip module. +%endif + +%package mod-http-image-filter +Summary: HTTP image filter module for nginx +BuildRequires: gd-devel +Requires: nginx gd + +%description mod-http-image-filter +Nginx HTTP image filter module. + +%package mod-http-perl +Summary: HTTP perl module for nginx +BuildRequires: perl-devel perl(ExtUtils::Embed) +Requires: nginx perl(constant) +Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) + +%description mod-http-perl +Nginx HTTP perl module. + +%package mod-http-xslt-filter +Summary: XSLT module for nginx +BuildRequires: libxslt-devel +Requires: nginx + +%description mod-http-xslt-filter +Nginx XSLT module. + +%package mod-mail +Summary: mail modules for nginx +Requires: nginx + +%description mod-mail +Nginx mail modules + +%package mod-stream +Summary: stream modules for nginx +Requires: nginx + +%description mod-stream +Nginx stream modules. + +%package_help + +%prep +%autosetup -n %{name}-%{version} -p1 +cp %{SOURCE200} %{SOURCE210} %{SOURCE10} %{SOURCE12} . + +%build +export DESTDIR=%{buildroot} +nginx_ldopts="$RPM_LD_FLAGS -Wl,-E" +if ! ./configure \ + --prefix=%{_datadir}/nginx --sbin-path=%{_sbindir}/nginx --modules-path=%{_libdir}/nginx/modules \ + --conf-path=%{_sysconfdir}/nginx/nginx.conf --error-log-path=%{_localstatedir}/log/nginx/error.log \ + --http-log-path=%{_localstatedir}/log/nginx/access.log \ + --http-client-body-temp-path=%{_localstatedir}/lib/nginx/tmp/client_body \ + --http-fastcgi-temp-path=%{_localstatedir}/lib/nginx/tmp/fastcgi \ + --http-proxy-temp-path=%{_localstatedir}/lib/nginx/tmp/proxy \ + --http-scgi-temp-path=%{_localstatedir}/lib/nginx/tmp/scgi \ + --http-uwsgi-temp-path=%{_localstatedir}/lib/nginx/tmp/uwsgi \ + --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx \ + --user=%{nginx_user} --group=%{nginx_user} \ +%if 0%{?with_aio} + --with-file-aio \ +%endif + --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module \ + --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic \ +%if %{with geoip} + --with-http_geoip_module=dynamic \ +%endif + --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module \ + --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module \ + --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module \ + --with-http_perl_module=dynamic --with-http_auth_request_module \ + --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic \ + --with-stream_ssl_module --with-google_perftools_module --with-debug \ + --with-cc-opt="%{optflags} $(pcre-config --cflags)" --with-ld-opt="$nginx_ldopts"; then + : configure failed + cat objs/autoconf.err + exit 1 +fi + +%make_build + + +%install +%make_install INSTALLDIRS=vendor + +find %{buildroot} -type f -empty -exec rm -f '{}' \; +find %{buildroot} -type f -name .packlist -exec rm -f '{}' \; +find %{buildroot} -type f -name perllocal.pod -exec rm -f '{}' \; +find %{buildroot} -type f -iname '*.so' -exec chmod 0755 '{}' \; + +pushd %{buildroot} +install -p -D -m 0644 %{_builddir}/nginx-%{version}/nginx.service .%{_unitdir}/nginx.service +install -p -D -m 0644 %{SOURCE11} .%{_sysconfdir}/logrotate.d/nginx +install -p -d -m 0755 .%{_sysconfdir}/systemd/system/nginx.service.d +install -p -d -m 0755 .%{_unitdir}/nginx.service.d +install -p -d -m 0755 .%{_sysconfdir}/nginx/conf.d +install -p -d -m 0755 .%{_sysconfdir}/nginx/default.d +install -p -d -m 0700 .%{_localstatedir}/lib/nginx +install -p -d -m 0700 .%{_localstatedir}/lib/nginx/tmp +install -p -d -m 0700 .%{_localstatedir}/log/nginx +install -p -d -m 0755 .%{_datadir}/nginx/html +install -p -d -m 0755 .%{_datadir}/nginx/modules +install -p -d -m 0755 .%{_libdir}/nginx/modules +install -p -m 0644 %{_builddir}/nginx-%{version}/nginx.conf .%{_sysconfdir}/nginx +install -p -m 0644 %{SOURCE100} .%{_datadir}/nginx/html +install -p -m 0644 %{SOURCE102} .%{_datadir}/nginx/html +install -p -m 0644 %{SOURCE103} %{SOURCE104} .%{_datadir}/nginx/html + +%if 0%{?with_mailcap_mimetypes} +rm -f .%{_sysconfdir}/nginx/mime.types +%endif + +install -p -D -m 0644 %{_builddir}/nginx-%{version}/man/nginx.8 .%{_mandir}/man8/nginx.8 +install -p -D -m 0755 %{SOURCE13} .%{_bindir}/nginx-upgrade +popd + +for i in ftdetect indent syntax; do + install -p -D -m644 contrib/vim/${i}/nginx.vim %{buildroot}%{_datadir}/vim/vimfiles/${i}/nginx.vim +done + +%if %{with geoip} +echo 'load_module "%{_libdir}/nginx/modules/ngx_http_geoip_module.so";' \ + > %{buildroot}%{_datadir}/nginx/modules/mod-http-geoip.conf +%endif + +pushd %{buildroot} +echo 'load_module "%{_libdir}/nginx/modules/ngx_http_image_filter_module.so";' \ + > .%{_datadir}/nginx/modules/mod-http-image-filter.conf +echo 'load_module "%{_libdir}/nginx/modules/ngx_http_perl_module.so";' \ + > .%{_datadir}/nginx/modules/mod-http-perl.conf +echo 'load_module "%{_libdir}/nginx/modules/ngx_http_xslt_filter_module.so";' \ + > .%{_datadir}/nginx/modules/mod-http-xslt-filter.conf +echo 'load_module "%{_libdir}/nginx/modules/ngx_mail_module.so";' \ + > .%{_datadir}/nginx/modules/mod-mail.conf +echo 'load_module "%{_libdir}/nginx/modules/ngx_stream_module.so";' \ + > .%{_datadir}/nginx/modules/mod-stream.conf +popd + +%pre filesystem +getent group %{nginx_user} > /dev/null || groupadd -r %{nginx_user} +getent passwd %{nginx_user} > /dev/null || useradd -r -d %{_localstatedir}/lib/nginx -g %{nginx_user} \ + -s /sbin/nologin -c "Nginx web server" %{nginx_user} +exit 0 + +%post +%systemd_post nginx.service + +%if %{with geoip} +%post mod-http-geoip +if [ $1 -eq 1 ]; then + systemctl reload nginx.service >/dev/null 2>&1 || : +fi +%endif + +%post mod-http-image-filter +if [ $1 -eq 1 ]; then + systemctl reload nginx.service >/dev/null 2>&1 || : +fi + +%post mod-http-perl +if [ $1 -eq 1 ]; then + systemctl reload nginx.service >/dev/null 2>&1 || : +fi + +%post mod-http-xslt-filter +if [ $1 -eq 1 ]; then + systemctl reload nginx.service >/dev/null 2>&1 || : +fi + +%post mod-mail +if [ $1 -eq 1 ]; then + systemctl reload nginx.service >/dev/null 2>&1 || : +fi + +%post mod-stream +if [ $1 -eq 1 ]; then + systemctl reload nginx.service >/dev/null 2>&1 || : +fi + +%preun +%systemd_preun nginx.service + +%postun +%systemd_postun nginx.service +if [ $1 -ge 1 ]; then + /usr/bin/nginx-upgrade >/dev/null 2>&1 || : +fi + +%files +%defattr(-,root,root) +%license LICENSE +%config(noreplace) %{_sysconfdir}/nginx/* +%config(noreplace) %{_sysconfdir}/logrotate.d/nginx +%exclude %{_sysconfdir}/nginx/conf.d +%exclude %{_sysconfdir}/nginx/default.d +%if 0%{?with_mailcap_mimetypes} +%exclude %{_sysconfdir}/nginx/mime.types +%endif +%{_bindir}/nginx-upgrade +%{_sbindir}/nginx +%dir %{_libdir}/nginx/modules +%attr(770,%{nginx_user},root) %dir %{_localstatedir}/lib/nginx +%attr(770,%{nginx_user},root) %dir %{_localstatedir}/lib/nginx/tmp +%{_unitdir}/nginx.service +%{_datadir}/nginx/html/* +%{_datadir}/vim/vimfiles/ftdetect/nginx.vim +%{_datadir}/vim/vimfiles/syntax/nginx.vim +%{_datadir}/vim/vimfiles/indent/nginx.vim +%attr(770,%{nginx_user},root) %dir %{_localstatedir}/log/nginx + +%files all-modules + +%files filesystem +%dir %{_sysconfdir}/nginx +%dir %{_sysconfdir}/nginx/{conf.d,default.d} +%dir %{_sysconfdir}/systemd/system/nginx.service.d +%dir %{_unitdir}/nginx.service.d +%dir %{_datadir}/nginx +%dir %{_datadir}/nginx/html + +%if %{with geoip} +%files mod-http-geoip +%{_libdir}/nginx/modules/ngx_http_geoip_module.so +%{_datadir}/nginx/modules/mod-http-geoip.conf +%endif + +%files mod-http-image-filter +%{_libdir}/nginx/modules/ngx_http_image_filter_module.so +%{_datadir}/nginx/modules/mod-http-image-filter.conf + +%files mod-http-perl +%{_libdir}/nginx/modules/ngx_http_perl_module.so +%{_datadir}/nginx/modules/mod-http-perl.conf +%dir %{perl_vendorarch}/auto/nginx +%{perl_vendorarch}/nginx.pm +%{perl_vendorarch}/auto/nginx/nginx.so + +%files mod-http-xslt-filter +%{_libdir}/nginx/modules/ngx_http_xslt_filter_module.so +%{_datadir}/nginx/modules/mod-http-xslt-filter.conf + +%files mod-mail +%{_libdir}/nginx/modules/ngx_mail_module.so +%{_datadir}/nginx/modules/mod-mail.conf + +%files mod-stream +%{_libdir}/nginx/modules/ngx_stream_module.so +%{_datadir}/nginx/modules/mod-stream.conf + +%files help +%defattr(-,root,root) +%doc CHANGES README README.dynamic +%{_mandir}/man3/nginx.3pm* +%{_mandir}/man8/nginx.8* + +%changelog +* Thu Sep 3 2020 yanan li - 1:1.18.0-2 +- add mime.types file to nginx packages + +* Thu Jun 4 2020 huanghaitao - 1:1.18.0-1 +- Change source to latest update + +* Fri May 22 2020 wutao - 1:1.16.1-4 +- change and delete html + +* Mon May 11 2020 wutao - 1:1.16.1-3 +- modify patch and html + +* Wed Mar 18 2020 yuxiangyang - 1:1.16.1-2 +- delete http_stub_status_module.This configuration creates a simple + web page with basic status data,but it will affect cpu scale-out because + it use atomic cas. + +* Mon Mar 16 2020 likexin - 1:1.16.1-1 +- update to 1.16.1 + +* Mon Mar 16 2020 openEuler Buildteam - 1:1.12.1-17 +- Type:bugfix +- ID:NA +- SUG:restart +- DESC: fix CVE-2019-20372 + +* Sat Dec 28 2019 openEuler Buildteam - 1:1.12.1-16 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC: add the with_mailcap_mimetypes + +* Wed Dec 4 2019 openEuler Buildteam - 1:1.12.1-15 +- Package init + diff --git a/test/ac/acl/package_yaml/repo_test_sample/hg_test/hg_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/hg_test/hg_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2b313a57db912e5e807a88ccb748a09d029c16c3 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/hg_test/hg_test.yaml @@ -0,0 +1,4 @@ +version_control: hg +src_repo: https://hg.nginx.org/nginx +tag_prefix: release- +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/metacpan_test/metacpan_test.spec b/test/ac/acl/package_yaml/repo_test_sample/metacpan_test/metacpan_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..2c119db61ad4230d6c4a6d33633e87d6ee7a897a --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/metacpan_test/metacpan_test.spec @@ -0,0 +1,54 @@ +Name: perl-HTML-Tagset +Version: 3.20 +Release: 37 +Summary: HTML::Tagset - data tables useful in parsing HTML +License: GPL+ or Artistic +URL: https://metacpan.org/release/HTML-Tagset +Source0: https://cpan.metacpan.org/authors/id/P/PE/PETDANCE/HTML-Tagset-%{version}.tar.gz + +BuildArch: noarch + +BuildRequires: perl-generators perl-interpreter perl(:VERSION) >= 5.4 +BuildRequires: perl(ExtUtils::MakeMaker) >= 6.76 perl(strict) perl(vars) +BuildRequires: perl(Test) perl(Test::More) +BuildRequires: perl(Test::Pod) >= 1.14 + +Requires: perl(:MODULE_COMPAT_%(eval "`perl -V:version`"; echo $version)) + +%description +This module contains data tables useful in dealing with HTML. +It provides no functions or methods. + +%package help +Summary: Documentation for perl-HTML-Tagset + +%description help +Documentation for perl-HTML-Tagset. + +%prep +%autosetup -n HTML-Tagset-%{version} -p1 + +%build +perl Makefile.PL INSTALLDIRS=vendor NO_PACKLIST=1 +%make_build + +%install +make pure_install DESTDIR=%{buildroot} +%{_fixperms} %{buildroot} + +%check +make test + +%files +%{perl_vendorlib}/HTML/ +%exclude %{_libdir}/perl5/perllocal.pod + +%files help +%doc Changes README +%{_mandir}/man3/ + + +%changelog +* Tue Oct 22 2019 Zaiwang Li - 3.20-37 +- Init Package. + diff --git a/test/ac/acl/package_yaml/repo_test_sample/metacpan_test/metacpan_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/metacpan_test/metacpan_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6720c745b66f6bb9a40d4977c6258ac144c418a1 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/metacpan_test/metacpan_test.yaml @@ -0,0 +1,4 @@ +version_control: metacpan +src_repo: HTML-Tagset +tag_prefix: "v" +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/na_test/na.spec b/test/ac/acl/package_yaml/repo_test_sample/na_test/na.spec new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/ac/acl/package_yaml/repo_test_sample/na_test/na.yaml b/test/ac/acl/package_yaml/repo_test_sample/na_test/na.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fa0b9febce760582cbb15012156d1bd5d22f127a --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/na_test/na.yaml @@ -0,0 +1,4 @@ +version_control: NA +src_repo: NA +tag_prefix: NA +separator: NA \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/pypi_test/pypi_test.spec b/test/ac/acl/package_yaml/repo_test_sample/pypi_test/pypi_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..f73c2a10c9ca82f8acd3c1215deed72d5496e22f --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/pypi_test/pypi_test.spec @@ -0,0 +1,110 @@ +Name: python-idna +Version: 2.10 +Release: 1 +Summary: Internationalized Domain Names in Applications (IDNA) +License: BSD and Python and Unicode +URL: https://github.com/kjd/idna +Source0: https://files.pythonhosted.org/packages/source/i/idna/idna-%{version}.tar.gz + +BuildArch: noarch +%if 0%{?with_python2} +BuildRequires: python2-devel python2-setuptools +%endif +%if 0%{?with_python3} +BuildRequires: python3-devel python3-setuptools +%endif + +%description +A library to support the Internationalised Domain Names in +Applications (IDNA) protocol as specified in RFC 5891 +http://tools.ietf.org/html/rfc5891. This version of the protocol +is often referred to as “IDNA2008” and can produce different +results from the earlier standard from 2003. + +The library is also intended to act as a suitable drop-in replacement +for the “encodings.idna” module that comes with the Python standard +library but currently only supports the older 2003 specification. + +%if 0%{?with_python2} +%package -n python2-idna +Summary: Python2 package for python-idna +Provides: python-idna = %{version}-%{release} +Obsoletes: python-idna < %{version}-%{release} + +%description -n python2-idna +Python2 package for python-idna +%endif + +%if 0%{?with_python3} +%package -n python3-idna +Summary: Python3 package for python-idna +%{?python_provide: %python_provide python3-idna} + +%description -n python3-idna +Python3 package for python-idna +%endif + +%prep +%autosetup -n idna-%{version} -p1 + +%build +%if 0%{?with_python2} +%py2_build +%endif + +%if 0%{?with_python3} +%py3_build +%endif + +%install +%if 0%{?with_python2} +%py2_install +%endif + +%if 0%{?with_python3} +%py3_install +%endif + +%check +%if 0%{?with_python2} +%{__python2} setup.py test +%endif + +%if 0%{?with_python3} +%{__python3} setup.py test +%endif + +%if 0%{?with_python2} +%files -n python2-idna +%defattr(-,root,root) +%doc README.rst HISTORY.rst +%license LICENSE.rst +%{python2_sitelib}/* +%endif + +%if 0%{?with_python3} +%files -n python3-idna +%defattr(-,root,root) +%doc README.rst HISTORY.rst +%license LICENSE.rst +%{python3_sitelib}/* +%endif + +%changelog +* Thu Jul 23 2020 zhouhaibo - 2.10-1 +- Package update + +* Wed Jan 15 2020 openEuler Buildteam - 2.8-3 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC:delete the python-idna + +* Tue Jan 14 2020 openEuler Buildteam - 2.8-2 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC:delete the python provides in python2 + +* Wed Sep 4 2019 openEuler Buildteam - 2.8-1 +- Package init diff --git a/test/ac/acl/package_yaml/repo_test_sample/pypi_test/pypi_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/pypi_test/pypi_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8f9dccbb3ddb50ec9d9473d0391edbc611039639 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/pypi_test/pypi_test.yaml @@ -0,0 +1,4 @@ +version_control: pypi +src_repo: idna +tag_prefix: "v" +separator: "." \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/repo_name_test/svn_test.spec b/test/ac/acl/package_yaml/repo_test_sample/repo_name_test/svn_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..8c21ec669c733fb5f013b97dad5401180fedcc1f --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/repo_name_test/svn_test.spec @@ -0,0 +1,87 @@ +Name: lame +Version: 3.100 +Release: 7 +Summary: Free MP3 audio compressor +License: GPLv2+ +URL: http://lame.sourceforge.net/ +Source0: http://downloads.sourceforge.net/sourceforge/lam/lam-3.100.tar.gz +Patch0001: lame-noexecstack.patch +Patch0002: libmp3lame-symbols.patch + +BuildRequires: ncurses-devel gtk+-devel + +Provides: %{name}-libs = %{version}-%{release} +Obsoletes: %{name}-libs < %{version}-%{release} + +%description +LAME is a high quality MPEG Audio Layer III (MP3) encoder. + +%package devel +Summary: Development files for lame +Requires: %{name} = %{version}-%{release} + +%description devel +The lame-devel package contains development files for lame. + +%package help +Summary: man info for lame + +%description help +The lame-help Package contains man info for lame. + +%package mp3x +Summary: MP3 frame analyzer +Requires: %{name} = %{version}-%{release} + +%description mp3x +The lame-mp3x package contains the mp3x frame analyzer. + + +%prep +%autosetup -p1 + + +%build +sed -i -e 's/^\(\s*hardcode_libdir_flag_spec\s*=\).*/\1/' configure +%configure \ + --disable-dependency-tracking --disable-static --enable-mp3x --enable-mp3rtp +%make_build + + +%install +%make_install +%delete_la +ln -sf lame/lame.h %{buildroot}%{_includedir}/lame.h + + +%check +make test + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + + +%files +%exclude %{_docdir}/%{name} +%doc README TODO USAGE doc/html/*.html ChangeLog COPYING LICENSE +%{_bindir}/{lame,mp3rtp} +%{_libdir}/libmp3lame.so.0* + +%files devel +%exclude %{_docdir}/%{name} +%doc API HACKING STYLEGUIDE +%{_libdir}/libmp3lame.so +%{_includedir}/{lame,lame.h} + +%files help +%{_mandir}/man1/lame.1* + +%files mp3x +%{_bindir}/mp3x + +%changelog +* Thu Dec 12 2019 zoushuangshuang - 3.100-7 +- Package init diff --git a/test/ac/acl/package_yaml/repo_test_sample/repo_name_test/svn_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/repo_name_test/svn_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..34170dc04114a2389422aca358abe5df6e0d4b49 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/repo_name_test/svn_test.yaml @@ -0,0 +1,4 @@ +version_control: svn +src_repo: https://svn.code.sf.net/p/lame/svn +tag_prefix: "^lame" +separator: _ \ No newline at end of file diff --git a/test/ac/acl/package_yaml/repo_test_sample/rubygem_test/rubygem_test.spec b/test/ac/acl/package_yaml/repo_test_sample/rubygem_test/rubygem_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..a7b69c26be5130c7f1206d08a6b708d1e325ea10 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/rubygem_test/rubygem_test.spec @@ -0,0 +1,64 @@ +%global gem_name idn +Name: rubygem-%{gem_name} +Version: 0.0.2 +Release: 1 +Summary: Ruby Bindings for the GNU LibIDN library +License: ASL 2.0 and LGPLv2+ +URL: https://rubygems.org/gems/idn +Source0: https://rubygems.org/gems/%{gem_name}-%{version}.gem +Patch0: rubygem-idn-0.0.2-Fix-for-ruby-1.9.x.patch +Patch1: rubygem-idn-0.0.2-ruby2-encoding-in-tests-fix.patch +BuildRequires: ruby(release) rubygems-devel ruby-devel gcc libidn-devel rubygem(test-unit) +%description +Ruby Bindings for the GNU LibIDN library, an implementation of the Stringprep, +Punycode and IDNA specifications defined by the IETF Internationalized Domain +Names (IDN) working group. + +%package doc +Summary: Documentation for %{name} +Requires: %{name} = %{version}-%{release} +BuildArch: noarch +%description doc +Documentation for %{name}. + +%prep +%setup -q -n %{gem_name}-%{version} +%patch0 -p0 +%patch1 -p1 + +%build +gem build ../%{gem_name}-%{version}.gemspec +%gem_install + +%install +mkdir -p %{buildroot}%{gem_dir} +cp -a .%{gem_dir}/* \ + %{buildroot}%{gem_dir}/ +mkdir -p %{buildroot}%{gem_extdir_mri} +cp -a .%{gem_extdir_mri}/{gem.build_complete,*.so} %{buildroot}%{gem_extdir_mri}/ +rm -rf %{buildroot}%{gem_instdir}/ext/ + +%check +pushd .%{gem_instdir} +ruby -I$(dirs +1)%{gem_extdir_mri} -e 'Dir.glob "./test/tc_*.rb", &method(:require)' +popd + +%files +%dir %{gem_instdir} +%{gem_extdir_mri} +%license %{gem_instdir}/LICENSE +%exclude %{gem_libdir} +%exclude %{gem_cache} +%{gem_spec} + +%files doc +%doc %{gem_docdir} +%doc %{gem_instdir}/CHANGES +%doc %{gem_instdir}/NOTICE +%doc %{gem_instdir}/README +%{gem_instdir}/Rakefile +%{gem_instdir}/test + +%changelog +* Sat Jul 25 2020 wutao - 0.0.2-1 +- package init diff --git a/test/ac/acl/package_yaml/repo_test_sample/rubygem_test/rubygem_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/rubygem_test/rubygem_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2bfdd1734ef06d2b150d788850edbd7336b256d5 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/rubygem_test/rubygem_test.yaml @@ -0,0 +1,4 @@ +version_control: rubygem +src_repo: idn +tag_prefix: "" +separator: "." diff --git a/test/ac/acl/package_yaml/repo_test_sample/svn_test/svn_test.spec b/test/ac/acl/package_yaml/repo_test_sample/svn_test/svn_test.spec new file mode 100644 index 0000000000000000000000000000000000000000..fcd2463066774b3af9513a39dff239b88c7eaaee --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/svn_test/svn_test.spec @@ -0,0 +1,87 @@ +Name: lame +Version: 3.100 +Release: 7 +Summary: Free MP3 audio compressor +License: GPLv2+ +URL: http://lame.sourceforge.net/ +Source0: http://downloads.sourceforge.net/sourceforge/lame/%{name}-%{version}.tar.gz +Patch0001: lame-noexecstack.patch +Patch0002: libmp3lame-symbols.patch + +BuildRequires: ncurses-devel gtk+-devel + +Provides: %{name}-libs = %{version}-%{release} +Obsoletes: %{name}-libs < %{version}-%{release} + +%description +LAME is a high quality MPEG Audio Layer III (MP3) encoder. + +%package devel +Summary: Development files for lame +Requires: %{name} = %{version}-%{release} + +%description devel +The lame-devel package contains development files for lame. + +%package help +Summary: man info for lame + +%description help +The lame-help Package contains man info for lame. + +%package mp3x +Summary: MP3 frame analyzer +Requires: %{name} = %{version}-%{release} + +%description mp3x +The lame-mp3x package contains the mp3x frame analyzer. + + +%prep +%autosetup -p1 + + +%build +sed -i -e 's/^\(\s*hardcode_libdir_flag_spec\s*=\).*/\1/' configure +%configure \ + --disable-dependency-tracking --disable-static --enable-mp3x --enable-mp3rtp +%make_build + + +%install +%make_install +%delete_la +ln -sf lame/lame.h %{buildroot}%{_includedir}/lame.h + + +%check +make test + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + + +%files +%exclude %{_docdir}/%{name} +%doc README TODO USAGE doc/html/*.html ChangeLog COPYING LICENSE +%{_bindir}/{lame,mp3rtp} +%{_libdir}/libmp3lame.so.0* + +%files devel +%exclude %{_docdir}/%{name} +%doc API HACKING STYLEGUIDE +%{_libdir}/libmp3lame.so +%{_includedir}/{lame,lame.h} + +%files help +%{_mandir}/man1/lame.1* + +%files mp3x +%{_bindir}/mp3x + +%changelog +* Thu Dec 12 2019 zoushuangshuang - 3.100-7 +- Package init diff --git a/test/ac/acl/package_yaml/repo_test_sample/svn_test/svn_test.yaml b/test/ac/acl/package_yaml/repo_test_sample/svn_test/svn_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..34170dc04114a2389422aca358abe5df6e0d4b49 --- /dev/null +++ b/test/ac/acl/package_yaml/repo_test_sample/svn_test/svn_test.yaml @@ -0,0 +1,4 @@ +version_control: svn +src_repo: https://svn.code.sf.net/p/lame/svn +tag_prefix: "^lame" +separator: _ \ No newline at end of file diff --git a/test/ac/acl/package_yaml/test_check_repo.py b/test/ac/acl/package_yaml/test_check_repo.py new file mode 100644 index 0000000000000000000000000000000000000000..3de78eba7ff66786d466881b0fa3b14026f17a65 --- /dev/null +++ b/test/ac/acl/package_yaml/test_check_repo.py @@ -0,0 +1,117 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-17 +# Description: test for check_repo.py +# ***********************************************************************************/ +""" + +import unittest +import mock +import os +import yaml +import logging.config +import logging +import shutil + +from src.ac.acl.package_yaml.check_repo import ReleaseTagsFactory + +logging.getLogger('test_logger') + +class TestGetReleaseTags(unittest.TestCase): + TEST_YAML_DIR = { + "hg": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/hg_test/hg_test.yaml"), + "github": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/github_test/github_test.yaml"), + "git": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/git_test/git_test.yaml"), + "gitlab.gnome": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.yaml"), + "svn": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/svn_test/svn_test.yaml"), + "metacpan": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/metacpan_test/metacpan_test.yaml"), + "pypi": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/pypi_test/pypi_test.yaml"), + "rubygem": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/rubygem_test/rubygem_test.yaml"), + "gitee": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gitee_test/gitee_test.yaml"), + "gnu-ftp": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gnu_ftp_test/gnu_ftp_test.yaml") + } + + def _load_yaml(self, filepath): + result = {} + try: + with open(filepath, 'r') as yaml_data: # load yaml data + result = yaml.safe_load(yaml_data) + except IOError as e: + logging.warning("package yaml not exist. {}".format(str(e))) + except yaml.YAMLError as exc: + logging.warning("Error parsering YAML: {}".format(str(exc))) + finally: + return result + + def _get_test_tags(self, version): + yaml_content = self._load_yaml(self.TEST_YAML_DIR[version]) + vc = yaml_content.get("version_control", "") + sr = yaml_content.get("src_repo", "") + release_tags = ReleaseTagsFactory.get_release_tags(vc) + return release_tags.get_tags(sr) + + def test_get_hg_release_tags(self): + release_tags = self._get_test_tags("hg") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_github_release_tags(self): + release_tags = self._get_test_tags("github") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_git_release_tags(self): + release_tags = self._get_test_tags("git") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_gitlab_gnome_release_tags(self): + release_tags = self._get_test_tags("gitlab.gnome") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_svn_release_tags(self): + release_tags = self._get_test_tags("svn") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_metacpan_release_tags(self): + release_tags = self._get_test_tags("metacpan") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_pypi_release_tags(self): + release_tags = self._get_test_tags("pypi") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_rubygem_release_tags(self): + release_tags = self._get_test_tags("rubygem") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_gitee_release_tags(self): + release_tags = self._get_test_tags("gitee") + self.assertEqual(len(release_tags) > 0, True) + + def test_get_gnu_ftp_release_tags(self): + release_tags = self._get_test_tags("gnu-ftp") + self.assertEqual(len(release_tags) > 0, True) + +if __name__ == '__main__': + work_dir = os.getcwd() + _ = not os.path.exists("log") and os.mkdir("log") + logger_conf_path = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../../../src/conf/logger.conf")) + logging.config.fileConfig(logger_conf_path) + logger = logging.getLogger("test_logger") + # Test get release tags + suite = unittest.makeSuite(TestGetReleaseTags) + unittest.TextTestRunner().run(suite) + os.chdir(work_dir) + shutil.rmtree("log") + + + diff --git a/test/ac/acl/package_yaml/test_check_yaml.py b/test/ac/acl/package_yaml/test_check_yaml.py new file mode 100644 index 0000000000000000000000000000000000000000..0a189bae62142e631354e0a3cb9100b3a95658e9 --- /dev/null +++ b/test/ac/acl/package_yaml/test_check_yaml.py @@ -0,0 +1,352 @@ +# -*- encoding=utf-8 -*- +""" +# *********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v1 for more details. +# Author: DisNight +# Create: 2020-09-17 +# Description: test for check_yaml.py +# ***********************************************************************************/ +""" + +import unittest +import mock +import sys +import os +import types +import logging.config +import logging +import shutil + +from src.ac.common.rpm_spec_adapter import RPMSpecAdapter +from src.proxy.git_proxy import GitProxy +from src.ac.common.gitee_repo import GiteeRepo +from src.ac.acl.package_yaml.check_yaml import CheckPackageYaml +from src.ac.framework.ac_result import FAILED, WARNING, SUCCESS +from src.ac.acl.package_yaml.check_repo import HgReleaseTags, GithubReleaseTags, GitReleaseTags, \ + GitlabReleaseTags, SvnReleaseTags, MetacpanReleaseTags, \ + PypiReleaseTags, RubygemReleaseTags, GiteeReleaseTags, \ + GnuftpReleaseTags + +logging.getLogger('test_logger') + +class TestCheckYamlField(unittest.TestCase): + + TEST_YAML_DIR = { + "missing": os.path.join(os.path.dirname(os.path.realpath(__file__)), "fields_test_sample/missing.yaml"), + "standard": os.path.join(os.path.dirname(os.path.realpath(__file__)), "fields_test_sample/standard.yaml") + } + + def setUp(self): + self.cy = CheckPackageYaml("", "", "") + def set_yaml(self, file): + self._gr.yaml_file = file + self.cy.set_yaml = types.MethodType(set_yaml, self.cy, CheckPackageYaml) # python3该接口有变化 为实例动态绑定接口 + + def test_none_file(self): + self.cy.set_yaml(None) + result = self.cy.check_fields() + self.assertEqual(result, WARNING) + + def test_missing_fields(self): + self.cy.set_yaml(self.TEST_YAML_DIR["missing"]) + result = self.cy.check_fields() + self.assertEqual(result, WARNING) + + def test_standard_fields(self): + self.cy.set_yaml(self.TEST_YAML_DIR["standard"]) + result = self.cy.check_fields() + self.assertEqual(result, SUCCESS) + + +class TestCheckYamlRepo(unittest.TestCase): + + SUCCESS_TAG_LIST = ["0.0.0", "0.0.1"] + FAILED_TAG_LIST = [] + TEST_YAML_DIR = { + "na": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/na_test/na.yaml"), + "hg": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/hg_test/hg_test.yaml"), + "github": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/github_test/github_test.yaml"), + "git": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/git_test/git_test.yaml"), + "gitlab.gnome": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.yaml"), + "svn": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/svn_test/svn_test.yaml"), + "metacpan": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/metacpan_test/metacpan_test.yaml"), + "pypi": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/pypi_test/pypi_test.yaml"), + "rubygem": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/rubygem_test/rubygem_test.yaml"), + "gitee": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gitee_test/gitee_test.yaml"), + "gnu-ftp": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gnu_ftp_test/gnu_ftp_test.yaml") + } + + TEST_SPEC_DIR = { + "na": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/na_test/na.spec"), + "hg": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/hg_test/hg_test.spec"), + "github": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/github_test/github_test.spec"), + "git": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/git_test/git_test.spec"), + "gitlab.gnome": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gitlab_gnome_test/gitlab_gnome_test.spec"), + "svn": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/svn_test/svn_test.spec"), + "metacpan": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/metacpan_test/metacpan_test.spec"), + "pypi": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/pypi_test/pypi_test.spec"), + "rubygem": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/rubygem_test/rubygem_test.spec"), + "gitee": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gitee_test/gitee_test.spec"), + "gnu-ftp": os.path.join(os.path.dirname(os.path.realpath(__file__)), "repo_test_sample/gnu_ftp_test/gnu_ftp_test.spec") + } + + def setUp(self): + self.cy = CheckPackageYaml("", "", "") + def set_yaml(self, file): + self._gr.yaml_file = file + def set_spec(self, file): + self._spec = RPMSpecAdapter(file) + self.cy.set_yaml = types.MethodType(set_yaml, self.cy, CheckPackageYaml) # python3该接口有变化 为实例动态绑定接口 + self.cy.set_spec = types.MethodType(set_spec, self.cy, CheckPackageYaml) # python3该接口有变化 为实例动态绑定接口 + + def test_none_file(self): + self.cy.set_yaml(None) + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + def test_NA_repo(self): + self.cy.set_yaml(self.TEST_YAML_DIR["na"]) + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(HgReleaseTags, "get_tags") + def test_hg_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["hg"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(HgReleaseTags, "get_tags") + def test_hg_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["hg"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(GithubReleaseTags, "get_tags") + def test_github_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["github"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(GithubReleaseTags, "get_tags") + def test_github_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["github"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(GitReleaseTags, "get_tags") + def test_git_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["git"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(GitReleaseTags, "get_tags") + def test_git_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["git"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(GitlabReleaseTags, "get_tags") + def test_gitlab_gnome_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["gitlab.gnome"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(GitlabReleaseTags, "get_tags") + def test_gitlab_gnome_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["gitlab.gnome"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(SvnReleaseTags, "get_tags") + def test_svn_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["svn"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(SvnReleaseTags, "get_tags") + def test_svn_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["svn"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(MetacpanReleaseTags, "get_tags") + def test_metacpan_repoo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["metacpan"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(MetacpanReleaseTags, "get_tags") + def test_metacpan_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["metacpan"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(PypiReleaseTags, "get_tags") + def test_pypi_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["pypi"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(PypiReleaseTags, "get_tags") + def test_pypi_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["pypi"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(RubygemReleaseTags, "get_tags") + def test_rubygem_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["rubygem"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(RubygemReleaseTags, "get_tags") + def test_rubygem_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["rubygem"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(GiteeReleaseTags, "get_tags") + def test_gitee_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["gitee"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(GiteeReleaseTags, "get_tags") + def test_gitee_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["gitee"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + @mock.patch.object(GnuftpReleaseTags, "get_tags") + def test_gnu_ftp_repo_success(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["gnu-ftp"]) + mock_get_tags.return_value = self.SUCCESS_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, SUCCESS) + + @mock.patch.object(GnuftpReleaseTags, "get_tags") + def test_gnu_ftp_repo_failed(self, mock_get_tags): + self.cy.set_yaml(self.TEST_YAML_DIR["gnu-ftp"]) + mock_get_tags.return_value = self.FAILED_TAG_LIST + self.cy.check_fields() + result = self.cy.check_repo() + self.assertEqual(result, WARNING) + + +class TestCheckConsistency(unittest.TestCase): + DIR_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), + "repo_test_sample") + TEST_SAMPLE_DIR = { + "na": "na_test", + "hg": "hg_test", + "github": "github_test", + "git": "git_test", + "gitlab.gnome": "gitlab_gnome_test", + "svn": "svn_test", + "metacpan": "metacpan_test", + "pypi": "pypi_test", + "rubygem": "rubygem_test", + "gitee": "gitee_test", + "gnu-ftp": "gnu_ftp_test", + "reponame": "repo_name_test" + } + + def _test_repo_domain(self, dir_key, predict): + self.cy = CheckPackageYaml(TestCheckConsistency.DIR_PATH, + TestCheckConsistency.TEST_SAMPLE_DIR[dir_key], + None) + self.cy.check_fields() + result = self.cy.check_repo_domain() + self.assertEqual(result, predict) + + def test_common_repo_domain_success(self): + self._test_repo_domain("gitee", SUCCESS) + + def test_common_repo_domain_failed(self): + self._test_repo_domain("svn", WARNING) + + def test_gnome_repo_domain(self): + self._test_repo_domain("gitlab.gnome", SUCCESS) + + def test_pypi_repo_domain(self): + self._test_repo_domain("pypi", SUCCESS) + + def _test_repo_name(self, dir_key, predict): + self.cy = CheckPackageYaml(TestCheckConsistency.DIR_PATH, + TestCheckConsistency.TEST_SAMPLE_DIR[dir_key], + None) + self.cy.check_fields() + result = self.cy.check_repo_name() + self.assertEqual(result, predict) + + def test_common_repo_name_success(self): + self._test_repo_name("gitlab.gnome", SUCCESS) + + def test_common_repo_name_failed(self): + self._test_repo_name("reponame", WARNING) + + def test_svn_repo_name(self): + self._test_repo_name("svn", SUCCESS) + +if __name__ == '__main__': + _ = not os.path.exists("log") and os.mkdir("log") + logger_conf_path = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../../../src/conf/logger.conf")) + logging.config.fileConfig(logger_conf_path) + logger = logging.getLogger("test_logger") + # Test check yaml fields + suite = unittest.makeSuite(TestCheckYamlField) + unittest.TextTestRunner().run(suite) + # Test check yaml repo + suite = unittest.makeSuite(TestCheckYamlRepo) + unittest.TextTestRunner().run(suite) + # Test check repo name and repo domain + suite = unittest.makeSuite(TestCheckConsistency) + unittest.TextTestRunner().run(suite) + shutil.rmtree("log") \ No newline at end of file