#!/usr/bin/python3.9
|
#
|
# CDDL HEADER START
|
#
|
# The contents of this file are subject to the terms of the
|
# Common Development and Distribution License (the "License").
|
# You may not use this file except in compliance with the License.
|
#
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
# or http://www.opensolaris.org/os/licensing.
|
# See the License for the specific language governing permissions
|
# and limitations under the License.
|
#
|
# When distributing Covered Code, include this CDDL HEADER in each
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
# If applicable, add the following below this CDDL HEADER, with the
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
#
|
# CDDL HEADER END
|
#
|
# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
|
#
|
#
|
# incorporator - an utility to incorporate packages in a repo
|
#
|
|
import subprocess
|
import json
|
import sys
|
import getopt
|
import re
|
import os.path
|
from pkg.version import Version
|
|
Werror = False # set to true to exit with any warning
|
|
def warning(msg):
|
if Werror == True:
|
print("ERROR: %s" % msg, file=sys.stderr)
|
sys.exit(1)
|
else:
|
print("WARNING: %s" % msg, file=sys.stderr)
|
|
class Incorporation(object):
|
name = None
|
version = '5.11'
|
packages = {}
|
|
def __init__(self, name, version):
|
self.name = name
|
self.version = version
|
self.packages = {}
|
|
def __package_to_str(self, name, version):
|
# strip the :timestamp from the version string
|
version = version.split(':', 1)[0]
|
# strip the ,{build-release} from the version string
|
version = re.sub(",[\d\.]+", "", version)
|
|
return "depend fmri=%s@%s facet.version-lock.%s=true type=incorporate" % (name, version, name)
|
|
def add_package(self, name, version):
|
self.packages[name] = version
|
|
def __str__(self):
|
result = """
|
set name=pkg.fmri value=pkg:/%s@%s
|
set name=info.classification value="org.opensolaris.category.2008:Meta Packages/Incorporations"
|
set name=org.opensolaris.consolidation value=userland
|
set name=pkg.depend.install-hold value=core-os.userland
|
set name=pkg.summary value="userland consolidation incorporation (%s)"
|
set name=pkg.description value="This incorporation constrains packages from the userland consolidation"
|
""" % (self.name, self.version, self.name)
|
|
names = list(self.packages.keys())
|
names.sort()
|
for name in names:
|
result += (self.__package_to_str(name, self.packages[name]) + '\n')
|
|
return result
|
|
#
|
# This should probably use the pkg APIs at some point, but this appears to be
|
# a stable and less complicated interface to gathering information from the
|
# manifests in the package repo.
|
#
|
def get_incorporations(repository, publisher, inc_version='5.11'):
|
tmp = subprocess.Popen(["/usr/bin/pkgrepo", "list", "-F", "json",
|
"-s", repository,
|
"-p", publisher],
|
stdout=subprocess.PIPE,
|
universal_newlines=True)
|
incorporations = {}
|
packages = json.load(tmp.stdout)
|
inc_name='consolidation/userland/userland-incorporation'
|
|
# Check for multiple versions of packages in the repo, but keep track of
|
# the latest one.
|
versions = {}
|
for package in packages:
|
pkg_name = package['name']
|
pkg_version = package['version']
|
|
if pkg_name in versions:
|
warning("%s is in the repo at multiple versions (%s, %s)" % (pkg_name, pkg_version, versions[pkg_name]))
|
if(Version(package['version']) < Version(versions[pkg_name])):
|
pkg_version = versions[pkg_name]
|
versions[pkg_name] = pkg_version
|
|
for package in packages:
|
pkg_name = package['name']
|
pkg_version = package['version']
|
|
# skip older packages and those that explicitly don't want to be incorporated
|
# also skip the incorporation itself
|
if 'pkg.tmp.noincorporate' in package or pkg_version != versions[pkg_name] or pkg_name == inc_name:
|
continue
|
|
# We don't want to support multiple incorporations for now
|
# a dict inside a list inside a dict
|
# incorporate = package['pkg.tmp.incorporate'][0]['value']
|
|
# for inc_name in incorporate:
|
# if we haven't started to build this incorporation, create one.
|
if inc_name not in incorporations:
|
incorporations[inc_name] = Incorporation(inc_name, inc_version)
|
# find the incorporation and add the package
|
tmp = incorporations[inc_name]
|
tmp.add_package(pkg_name, pkg_version)
|
return incorporations
|
|
def main_func():
|
global Werror
|
|
try:
|
opts, pargs = getopt.getopt(sys.argv[1:], "c:s:p:v:d:w",
|
["repository=", "publisher=", "version=",
|
"consolidation=", "destdir=", "Werror"])
|
except getopt.GetoptError as e:
|
usage(_("illegal option: %s") % e.opt)
|
|
repository = None
|
publisher = None
|
version = None
|
destdir = None
|
consolidation = None
|
|
for opt, arg in opts:
|
if opt in ("-s", "--repository"):
|
repository = arg
|
elif opt in ("-p", "--publisher"):
|
publisher = arg
|
elif opt in ("-v", "--version"):
|
version = arg
|
elif opt in ("-d", "--destdir"):
|
destdir = arg
|
elif opt in ("-c", "--consolidation"):
|
consolidation = arg
|
elif opt in ("-w", "--Werror"):
|
Werror = True
|
|
incorporations = get_incorporations(repository, publisher, version)
|
|
for incorporation_name in list(incorporations.keys()):
|
filename = ''
|
if destdir != None:
|
filename = destdir + '/'
|
filename += os.path.basename(incorporation_name) + '.p5m'
|
|
print("Writing %s manifest to %s" % (incorporation_name, filename))
|
fd = open(filename, "w+")
|
fd.write(str(incorporations[incorporation_name]))
|
fd.close()
|
|
if __name__ == "__main__":
|
main_func()
|