Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package product-composer for openSUSE:Factory checked in at 2024-02-07 18:49:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/product-composer (Old) and /work/SRC/openSUSE:Factory/.product-composer.new.1815 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "product-composer" Wed Feb 7 18:49:49 2024 rev:4 rq:1144804 version:0.3.3 Changes: -------- --- /work/SRC/openSUSE:Factory/product-composer/product-composer.changes 2024-01-12 23:46:54.109837164 +0100 +++ /work/SRC/openSUSE:Factory/.product-composer.new.1815/product-composer.changes 2024-02-07 18:51:59.486469435 +0100 @@ -1,0 +2,12 @@ +Tue Feb 6 15:13:11 UTC 2024 - Adrian Schröter <adr...@suse.de> + +- update to version 0.3.3 + - fixes incorrect data inside of repomd.xml + +------------------------------------------------------------------- +Mon Feb 5 12:04:37 UTC 2024 - Adrian Schröter <adr...@suse.de> + +- update to version 0.3.2 + * crash fixes + +------------------------------------------------------------------- Old: ---- product-composer-0.3.1.obscpio New: ---- product-composer-0.3.3.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ product-composer.spec ++++++ --- /var/tmp/diff_new_pack.GxuZ6D/_old 2024-02-07 18:51:59.922485121 +0100 +++ /var/tmp/diff_new_pack.GxuZ6D/_new 2024-02-07 18:51:59.926485265 +0100 @@ -17,7 +17,7 @@ Name: product-composer -Version: 0.3.1 +Version: 0.3.3 Release: 0 Summary: Product Composer License: GPL-2.0-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.GxuZ6D/_old 2024-02-07 18:51:59.950486128 +0100 +++ /var/tmp/diff_new_pack.GxuZ6D/_new 2024-02-07 18:51:59.954486273 +0100 @@ -2,14 +2,14 @@ <service name="obs_scm" mode="manual"> <param name="url">https://github.com/openSUSE/product-composer</param> <param name="scm">git</param> - <param name="version">0.3.1</param> - <param name="revision">0.3.1</param> + <param name="version">0.3.3</param> + <param name="revision">0.3.3</param> </service> + <service name="set_version" mode="manual" /> <service name="tar" mode="buildtime" /> <service name="recompress" mode="buildtime"> <param name="file">*.tar</param> <param name="compression">xz</param> </service> - <service name="set_version" mode="buildtime" /> </services> ++++++ product-composer-0.3.1.obscpio -> product-composer-0.3.3.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/product-composer-0.3.1/examples/ftp.productcompose new/product-composer-0.3.3/examples/ftp.productcompose --- old/product-composer-0.3.1/examples/ftp.productcompose 2024-01-11 10:04:08.000000000 +0100 +++ new/product-composer-0.3.3/examples/ftp.productcompose 2024-02-06 16:11:58.000000000 +0100 @@ -33,6 +33,7 @@ small: {} large_arm: architectures: [armv7l, aarch64] + name: Tumbleweed_ARM unpack: - unpackset diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/product-composer-0.3.1/src/productcomposer/cli.py new/product-composer-0.3.3/src/productcomposer/cli.py --- old/product-composer-0.3.1/src/productcomposer/cli.py 2024-01-11 10:04:08.000000000 +0100 +++ new/product-composer-0.3.3/src/productcomposer/cli.py 2024-02-06 16:11:58.000000000 +0100 @@ -61,6 +61,8 @@ # build command options build_parser.add_argument('-r', '--release', default=None, help='Define a build release counter') + build_parser.add_argument('--disturl', default=None, help='Define a disturl') + build_parser.add_argument('--vcs', default=None, help='Define a source repository identifier') build_parser.add_argument('--clean', action='store_true', help='Remove existing output directory first') build_parser.add_argument('out', help='Directory to write the result') @@ -108,7 +110,7 @@ parser.print_help() die(None) - yml, archlist = parse_yaml(args.filename, flavor) + yml = parse_yaml(args.filename, flavor) directory = os.getcwd() if args.filename.startswith('/'): directory = os.path.dirname(args.filename) @@ -121,10 +123,10 @@ if args.clean and os.path.exists(args.out): shutil.rmtree(args.out) - product_base_dir = get_product_dir(yml, flavor, archlist, args.release) + product_base_dir = get_product_dir(yml, flavor, args.release) kwdfile = args.filename.removesuffix('.productcompose') + '.kwd' - create_tree(args.out, product_base_dir, yml, pool, kwdfile, flavor, archlist) + create_tree(args.out, product_base_dir, yml, pool, kwdfile, flavor, args.vcs, args.disturl) def verify(args): @@ -140,30 +142,40 @@ if yml['product_compose_schema'] != 0 and yml['product_compose_schema'] != 0.1: die(f"Unsupported product composer schema: {yml['product_compose_schema']}") - archlist = None - if 'architectures' in yml: - archlist = yml['architectures'] + if yml['flavors'] is None: + yml['flavors'] = [] + if flavor: if 'flavors' not in yml or flavor not in yml['flavors']: die("Flavor not found: " + flavor) f = yml['flavors'][flavor] + # overwrite global values from flavor overwrites if 'architectures' in f: - archlist = f['architectures'] + yml['architectures'] = f['architectures'] + if 'name' in f: + yml['name'] = f['name'] + if 'summary' in f: + yml['summary'] = f['summary'] + if 'version' in f: + yml['version'] = f['version'] - if archlist is None: + if yml['architectures'] is None: die("No architecture defined") - return yml, archlist + if yml['build_options'] is None: + yml['build_options'] = [] + + return yml -def get_product_dir(yml, flavor, archlist, release): +def get_product_dir(yml, flavor, release): name = yml['name'] + "-" + str(yml['version']) if 'product_directory_name' in yml: # manual override name = yml['product_directory_name'] if flavor and not 'hide_flavor_in_product_directory_name' in yml['build_options']: name += "-" + flavor - if archlist: - visible_archs = archlist + if yml['architectures']: + visible_archs = yml['architectures'] if 'local' in visible_archs: visible_archs.remove('local') name += "-" + "-".join(visible_archs) @@ -186,7 +198,7 @@ die("Failed to run" + args[0], details=output) return popen.stdout.read() if stdout == subprocess.PIPE else '' -def create_tree(outdir, product_base_dir, yml, pool, kwdfile, flavor, archlist): +def create_tree(outdir, product_base_dir, yml, pool, kwdfile, flavor, vcs=None, disturl=None): if not os.path.exists(outdir): os.mkdir(outdir) @@ -214,17 +226,28 @@ elif yml['debug'] != 'include': die("Bad debug option, must be either 'include', 'split' or 'drop'") - for arch in archlist: + for arch in yml['architectures']: link_rpms_to_tree(rpmdir, yml, pool, arch, flavor, debugdir, sourcedir) - for arch in archlist: + for arch in yml['architectures']: unpack_meta_rpms(rpmdir, yml, pool, arch, flavor, medium=1) # only for first medium am - post_createrepo(rpmdir, yml['name']) + repos=[] + if disturl: + match = re.match("^obs://([^/]*)/([^/]*)/.*", disturl) + if match: + obsname = match.group(1) + project = match.group(2) + repo = f"obsproduct://{obsname}/{project}/{yml['name']}/{yml['version']}" + repos = [repo] + if vcs: + repos.append(vcs) + + post_createrepo(rpmdir, yml, content=["pool"], repos=repos) if debugdir: - post_createrepo(debugdir, yml['name'], content=["debug"]) + post_createrepo(debugdir, yml, content=["debug"], repos=repos) if sourcedir: - post_createrepo(sourcedir, yml['name'], content=["source"]) + post_createrepo(sourcedir, yml, content=["source"], repos=repos) if not os.path.exists(rpmdir + '/repodata'): return @@ -266,33 +289,44 @@ # repodata/*susedata* if os.path.exists("/usr/bin/add_product_susedata"): - args = [ "/usr/bin/add_product_susedata", '-u', - '-k', kwdfile, '-p', + args = [ "/usr/bin/add_product_susedata", + '-u', # unique filenames + '-g', # add gpg key ids as tags + '-k', kwdfile, + '-p', # diskusage data '-e', '/usr/share/doc/packages/eulas', '-d', rpmdir ] run_helper(args) - process_updateinfos(rpmdir, yml, pool, archlist, flavor, debugdir, sourcedir) + process_updateinfos(rpmdir, yml, pool, flavor, debugdir, sourcedir) # Add License File and create extra .license directory - if os.path.exists(rpmdir + "/license.tar.gz"): - run_helper(['gzip', '-d', rpmdir + "/license.tar.gz"], + licensefilename = 'license.tar' + if os.path.exists(rpmdir + '/license-' + yml['name'] + '.tar') or os.path.exists(rpmdir + '/license-' + yml['name'] + '.tar.gz'): + licensefilename = '/license-' + yml['name'] + '.tar' + if os.path.exists(rpmdir + licensefilename + '.gz'): + run_helper(['gzip', '-d', rpmdir + licensefilename + '.gz'], failmsg="Uncompress of license.tar.gz failed") - if os.path.exists(rpmdir + "/license.tar"): + if os.path.exists(rpmdir + licensefilename): licensedir = rpmdir + ".license" if not os.path.exists(licensedir): os.mkdir(licensedir) - args = [ 'tar', 'xf', rpmdir + "/license.tar", '-C', licensedir ] + args = [ 'tar', 'xf', rpmdir + licensefilename, '-C', licensedir ] output = run_helper(args, failmsg="extract license tar ball") if not os.path.exists(licensedir + "/license.txt"): die("No license.txt extracted", details=output) mr = ModifyrepoWrapper( - file=os.path.join(rpmdir, "license.tar"), + file=rpmdir + licensefilename, directory=os.path.join(rpmdir, "repodata"), ) mr.run_cmd() - os.unlink(rpmdir + '/license.tar') + os.unlink(rpmdir + licensefilename) + # meta package may bring a second file or expanded symlink, so we need clean up + if os.path.exists(rpmdir + '/license.tar'): + os.unlink(rpmdir + '/license.tar') + if os.path.exists(rpmdir + '/license.tar.gz'): + os.unlink(rpmdir + '/license.tar.gz') # detached signature args = [ '/usr/lib/build/signdummy', '-d', rpmdir + "/repodata/repomd.xml" ] @@ -352,7 +386,8 @@ # create media info files def create_media_dir(maindir, vendorstr, identstr, products): media1dir = maindir + '/' + 'media.1' - os.mkdir(media1dir) # we do only support seperate media atm + if not os.path.isdir(media1dir): + os.mkdir(media1dir) # we do only support seperate media atm with open(media1dir + '/media', 'w') as media_file: media_file.write(vendorstr + "\n") media_file.write(identstr + "\n") @@ -380,7 +415,7 @@ return entry # Add updateinfo.xml to metadata -def process_updateinfos(rpmdir, yml, pool, archlist, flavor, debugdir, sourcedir): +def process_updateinfos(rpmdir, yml, pool, flavor, debugdir, sourcedir): if not pool.updateinfos: return @@ -388,7 +423,7 @@ # build the union of the package sets for all requested architectures main_pkgset = PkgSet('main') - for arch in archlist: + for arch in yml['architectures']: pkgset = main_pkgset.add(create_package_set(yml, arch, flavor, 'main')) main_pkgset_names = main_pkgset.names() @@ -422,7 +457,7 @@ parent.remove(pkgentry) continue # ignore unwanted architectures - if pkgarch != 'noarch' and pkgarch not in archlist: + if pkgarch != 'noarch' and pkgarch not in yml['architectures']: parent.remove(pkgentry) continue @@ -459,17 +494,17 @@ die('Abort due to missing packages') -def post_createrepo(rpmdir, product_name, content=None): - # FIXME - distroname = "testgin" - - # FIXME - content = content or [] - # content.append("pool"] +def post_createrepo(rpmdir, yml, content=[], repos=[]): + product_name = yml['name'] + product_summary = yml['summary'] or yml['name'] + product_summary += " " + str(yml['version']) cr = CreaterepoWrapper(directory=".") - cr.distro = distroname - # cr.split = True + cr.distro = product_summary + # FIXME: /o is only for operating systems, we have nothing else atm + cr.cpeid = f"cpe:/o:{yml['vendor']}:{yml['name']}:{yml['version']}" + cr.repos = repos +# cr.split = True # cr.baseurl = "media://" cr.content = content cr.excludes = ["boot"] @@ -544,7 +579,7 @@ continue pkgset = PkgSet(name) pkgsets[name] = pkgset - if 'packages' in entry: + if 'packages' in entry and entry['packages']: pkgset.add_specs(entry['packages']) for setop in 'add', 'sub', 'intersect': if setop not in entry: @@ -624,7 +659,12 @@ os.mkdir(directory) outname = directory + '/' + os.path.basename(filename) if not os.path.exists(outname): - os.link(filename, outname) + if os.path.islink(filename): + # osc creates a repos/ structure with symlinks to it's cache + # but these would point outside of our media + shutil.copyfile(filename, outname) + else: + os.link(filename, outname) def link_entry_into_dir(entry, directory): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/product-composer-0.3.1/src/productcomposer/wrappers/createrepo.py new/product-composer-0.3.3/src/productcomposer/wrappers/createrepo.py --- old/product-composer-0.3.1/src/productcomposer/wrappers/createrepo.py 2024-01-11 10:04:08.000000000 +0100 +++ new/product-composer-0.3.3/src/productcomposer/wrappers/createrepo.py 2024-02-06 16:11:58.000000000 +0100 @@ -7,7 +7,9 @@ baseurl: str | None = Field() checksum_type: str = Field(default=defaults.CREATEREPO_CHECKSUM_TYPE) content: list[str] | None = Field() + cpeid: str | None = Field() distro: str | None = Field() + repos: list[str] | None = Field() excludes: list[str] | None = Field() general_compress_type: str = Field(default=defaults.CREATEREPO_GENERAL_COMPRESS_TYPE) split: bool = Field(default=False) @@ -28,12 +30,19 @@ cmd.append(f"--content={i}") if self.distro: - cmd.append(f"--distro={self.distro}") + if self.cpeid: + cmd.append(f"--distro={self.cpeid},{self.distro}") + else: + cmd.append(f"--distro={self.distro}") if self.excludes: for i in self.excludes: cmd.append(f"--excludes={i}") + if self.repos: + for i in self.repos: + cmd.append(f"--repo={i}") + if self.split: cmd.append("--split") ++++++ product-composer.obsinfo ++++++ --- /var/tmp/diff_new_pack.GxuZ6D/_old 2024-02-07 18:52:00.066490302 +0100 +++ /var/tmp/diff_new_pack.GxuZ6D/_new 2024-02-07 18:52:00.070490446 +0100 @@ -1,5 +1,5 @@ name: product-composer -version: 0.3.1 -mtime: 1704963848 -commit: d9d01296f0792fa2f999f66074b87219e5361503 +version: 0.3.3 +mtime: 1707232318 +commit: 8594a3e4b6c50d06612168973e396ea21ed910e5