userland-incorporator revision 5569
ac4e70ff8955669341f435bc0a734a17c01af124Mark Andrews#!/usr/bin/python2.7
885f47576842cf3c569315b9a48bd9f0ca03f203Automatic Updater#
71bd43eebd9d6e42dbcae62b730f5b6508d5acd8Automatic Updater# CDDL HEADER START
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater#
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater# The contents of this file are subject to the terms of the
2bb3422dc683c013db7042f5736240de6b86f182Automatic Updater# Common Development and Distribution License (the "License").
0bddff542cf2ae1b6595020f2f72ca482c6b438fAutomatic Updater# You may not use this file except in compliance with the License.
75b70a68aefaa17ac4e768d5ed85d2f50d471490Automatic Updater#
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
bb93c8542756719b53096b9939e4041d0966026fAutomatic Updater# or http://www.opensolaris.org/os/licensing.
c89d02f2fb4c06168236d600e86831cff324f763Mark Andrews# See the License for the specific language governing permissions
90ff38a0d8deaf5f9c2aa5916d99b2e572d28738Automatic Updater# and limitations under the License.
9e3a7b0faf417a10f5f689edf288807b2d5eedc5Brian Wellington#
ac4e70ff8955669341f435bc0a734a17c01af124Mark Andrews# When distributing Covered Code, include this CDDL HEADER in each
6c6a121295b30772cbf3dd75a51fb9d883051a0eAutomatic Updater# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e3a7b0faf417a10f5f689edf288807b2d5eedc5Brian Wellington# If applicable, add the following below this CDDL HEADER, with the
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater# fields enclosed by brackets "[]" replaced with your own identifying
bc0a53583d92309bebcf93c408e2f3247ebd3d3cAutomatic Updater# information: Portions Copyright [yyyy] [name of copyright owner]
56874aef380a64a2c183b7c282c3e7a361d67fa1Automatic Updater#
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews# CDDL HEADER END
96713299d08c0735c18ebe8772dd2cc1ecd4356aAutomatic Updater#
4b2cb1422c7c600fbc13b1cb06a8b4693bc11af8Mark Andrews# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews#
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews#
96713299d08c0735c18ebe8772dd2cc1ecd4356aAutomatic Updater# incorporator - an utility to incorporate packages in a repo
80faf1588895fd26490f82f95a7a1b771df1c324Automatic Updater#
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews
efb0e886f18894a1d2489f1ad74ad14b579e11c7Mark Andrewsimport subprocess
efb0e886f18894a1d2489f1ad74ad14b579e11c7Mark Andrewsimport json
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrewsimport sys
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafssonimport getopt
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrewsimport re
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrewsimport os.path
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafsson
aa1d397c4736cd86540555193d71e55fa3b37b2aMark AndrewsWerror = False # set to true to exit with any warning
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updaterdef warning(msg):
aa9c561961e9d877946ebaa8795fa2be054ab7bfEvan Hunt if Werror == True:
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater print >>sys.stderr, "ERROR: %s" % msg
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater sys.exit(1)
aa9c561961e9d877946ebaa8795fa2be054ab7bfEvan Hunt else:
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater print >>sys.stderr, "WARNING: %s" % msg
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updaterclass Incorporation(object):
aa9c561961e9d877946ebaa8795fa2be054ab7bfEvan Hunt name = None
2d2dc37599979c83495510f8af8d1756753aa2c5Automatic Updater version = '5.12'
2d2dc37599979c83495510f8af8d1756753aa2c5Automatic Updater packages = {}
aa9c561961e9d877946ebaa8795fa2be054ab7bfEvan Hunt
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater def __init__(self, name, version):
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater self.name = name
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater self.version = version
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater self.packages = {}
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater
cdfc81e048bd34c1d628380247bda6b80a89e20eAutomatic Updater def __package_to_str(self, name, version):
cdfc81e048bd34c1d628380247bda6b80a89e20eAutomatic Updater # strip the :timestamp from the version string
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater version = version.split(':', 1)[0]
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater # strip the ,{build-release} from the version string
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater version = re.sub(",[\d\.]+", "", version)
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater
eabc9c3c07cd956d3c436bd7614cb162dabdda76Mark Andrews return "depend fmri=%s@%s facet.version-lock.%s=true type=incorporate" % (name, version, name)
eabc9c3c07cd956d3c436bd7614cb162dabdda76Mark Andrews
eabc9c3c07cd956d3c436bd7614cb162dabdda76Mark Andrews def add_package(self, name, version):
9e3a7b0faf417a10f5f689edf288807b2d5eedc5Brian Wellington self.packages[name] = version
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews def __str__(self):
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater result = """
80faf1588895fd26490f82f95a7a1b771df1c324Automatic Updaterset name=pkg.fmri value=pkg:/%s@%s
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrewsset name=info.classification value="org.opensolaris.category.2008:Meta Packages/Incorporations"
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updaterset name=org.opensolaris.consolidation value=userland
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrewsset name=pkg.depend.install-hold value=core-os.userland
db5b7e2cdf150c46e8242d3e2e3ad3f5c7300258Automatic Updaterset name=pkg.summary value="userland consolidation incorporation (%s)"
80faf1588895fd26490f82f95a7a1b771df1c324Automatic Updaterset name=pkg.description value="This incorporation constrains packages from the userland consolidation"
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews""" % (self.name, self.version, self.name)
ca904804e43f663f08eb1ac9d6d617930b9a3cd3Automatic Updater
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews names = self.packages.keys()
db5b7e2cdf150c46e8242d3e2e3ad3f5c7300258Automatic Updater names.sort()
4b2cb1422c7c600fbc13b1cb06a8b4693bc11af8Mark Andrews for name in names:
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews result += (self.__package_to_str(name, self.packages[name]) + '\n')
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafsson return result
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews
efb0e886f18894a1d2489f1ad74ad14b579e11c7Mark Andrews#
efb0e886f18894a1d2489f1ad74ad14b579e11c7Mark Andrews# This should probably use the pkg APIs at some point, but this appears to be
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews# a stable and less complicated interface to gathering information from the
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafsson# manifests in the package repo.
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews#
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrewsdef get_incorporations(repository, publisher, inc_version='5.12',
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafsson static_file=None):
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews packages = {}
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater incorporations = {}
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater versions = {}
9174e44c14b1cb91a651fa1dc29470438c246ab9Automatic Updater
55e03fc54708d97917bf26639b987f759bdc1f44Automatic Updater #
9174e44c14b1cb91a651fa1dc29470438c246ab9Automatic Updater # if a static file was provided, prime the cache with the contents of
9174e44c14b1cb91a651fa1dc29470438c246ab9Automatic Updater # that file.
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont #
52367885450d8f61d4f2d63292beb15ba8f39ac7Automatic Updater if static_file:
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont with open(static_file, 'r') as fp:
2a31bd531072824ef252c18303859d6af7451b00Francis Dupont for line in fp:
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews line = line.partition('#')[0]
52367885450d8f61d4f2d63292beb15ba8f39ac7Automatic Updater line = line.rstrip()
9174e44c14b1cb91a651fa1dc29470438c246ab9Automatic Updater
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews try:
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater (incorporation, package, version) = re.split(':|@', line)
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater except ValueError:
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater pass
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater else:
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews if incorporation not in incorporations:
885f47576842cf3c569315b9a48bd9f0ca03f203Automatic Updater incorporations[incorporation] = Incorporation(incorporation, inc_version)
ae7e54b14c946e0984c191554db9abb4893f9349Automatic Updater # find the incorporation and add the package
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews tmp = incorporations[incorporation]
ae7e54b14c946e0984c191554db9abb4893f9349Automatic Updater tmp.add_package(package, version)
7af91d15b2ce1ce32f7320f6d5cc3b83621c241aAutomatic Updater versions[package] = version
efb0e886f18894a1d2489f1ad74ad14b579e11c7Mark Andrews
cdfc81e048bd34c1d628380247bda6b80a89e20eAutomatic Updater #
fe80a4909bf62b602feaf246866e9d29f7654194Automatic Updater # Load the repository for packages to incorporate.
fe80a4909bf62b602feaf246866e9d29f7654194Automatic Updater #
fe80a4909bf62b602feaf246866e9d29f7654194Automatic Updater if repository:
fe80a4909bf62b602feaf246866e9d29f7654194Automatic Updater tmp = subprocess.Popen(["/usr/bin/pkgrepo", "list", "-F", "json",
fe80a4909bf62b602feaf246866e9d29f7654194Automatic Updater "-s", repository,
fe80a4909bf62b602feaf246866e9d29f7654194Automatic Updater "-p", publisher],
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews stdout=subprocess.PIPE)
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafsson packages = json.load(tmp.stdout)
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews #
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafsson # Check for multiple versions of packages in the repo, but keep track of
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater # the latest one.
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater #
dd65eb1efb40b1c47d57963192bfc54873b219beAutomatic Updater for package in packages:
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews pkg_name = package['name']
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafsson pkg_version = package['version']
aa1d397c4736cd86540555193d71e55fa3b37b2aMark Andrews
d145b64cacc8d9cda51f9924ec70cd4661c3e2cfAutomatic Updater if pkg_name in versions:
0df8ead472f207020f8da22a185fe4b945248ab8Automatic Updater warning("%s is in the repo at multiple versions (%s, %s)" % (pkg_name, pkg_version, versions[pkg_name]))
e8c7dc2a5ce48f11c07a67c9923eeb8f419ff19fEvan Hunt pkg_version = max(pkg_version, versions[pkg_name])
0ce87e5749aabb8eef1e0a37e4bd6e6ffa1d7196Automatic Updater versions[pkg_name] = pkg_version
0ce87e5749aabb8eef1e0a37e4bd6e6ffa1d7196Automatic Updater
0df8ead472f207020f8da22a185fe4b945248ab8Automatic Updater #
2bb3422dc683c013db7042f5736240de6b86f182Automatic Updater # Add published packages to the incorporation lists
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater #
0df8ead472f207020f8da22a185fe4b945248ab8Automatic Updater for package in packages:
3b6e4c84a525b0b3fc9e8affd8bb9fa5c000345fAutomatic Updater pkg_name = package['name']
19b3dc94bce93fa76bd7e066f9298630dbc9dcb4Automatic Updater pkg_version = package['version']
d145b64cacc8d9cda51f9924ec70cd4661c3e2cfAutomatic Updater
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater # skip older packages and those that don't want to be incorporated
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater if 'pkg.tmp.incorporate' not in package or pkg_version != versions[pkg_name]:
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater continue
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater
0df8ead472f207020f8da22a185fe4b945248ab8Automatic Updater # a dict inside a list inside a dict
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater incorporate = package['pkg.tmp.incorporate'][0]['value']
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater
bc0a53583d92309bebcf93c408e2f3247ebd3d3cAutomatic Updater for inc_name in incorporate:
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater # if we haven't started to build this incorporation, create one.
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater if inc_name not in incorporations:
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater incorporations[inc_name] = Incorporation(inc_name, inc_version)
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater # find the incorporation and add the package
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater tmp = incorporations[inc_name]
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater tmp.add_package(pkg_name, pkg_version)
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater return incorporations
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater
7f94d9a8162c9a96b56e66176702b66e79d8e1a2Automatic Updaterdef main_func():
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater global Werror
19b3dc94bce93fa76bd7e066f9298630dbc9dcb4Automatic Updater
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater try:
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater opts, pargs = getopt.getopt(sys.argv[1:], "S:c:s:p:v:d:w",
7f94d9a8162c9a96b56e66176702b66e79d8e1a2Automatic Updater ["repository=", "publisher=", "version=",
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater "consolidation=", "destdir=", "Werror",
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater "static-content-file="])
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater except getopt.GetoptError, e:
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater usage(_("illegal option: %s") % e.opt)
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater
71bd43eebd9d6e42dbcae62b730f5b6508d5acd8Automatic Updater static_file = None
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater repository = None
7262eb86f2b465822206122921e2f357218f0cfdAutomatic Updater publisher = None
96ea71632887c58a9d00f47eb318bf76b35903c3Mark Andrews version = None
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater destdir = None
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater consolidation = None
bbb069be941f649228760edcc241122933c066d2Automatic Updater
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater for opt, arg in opts:
4cda4fd158d6ded5586bacea8c388445d99611eaAutomatic Updater if opt in ("-S", "--static-content-file"):
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews static_file = arg
b0d566a2ce0f5a67f537ee7f8233f82f2584cc61Automatic Updater elif opt in ("-s", "--repository"):
80faf1588895fd26490f82f95a7a1b771df1c324Automatic Updater repository = arg
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews elif opt in ("-p", "--publisher"):
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater publisher = arg
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater elif opt in ("-v", "--version"):
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews version = arg
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews elif opt in ("-d", "--destdir"):
5ae0e2c8b72fa44237edeb37d1945b1c3535ca39Automatic Updater destdir = arg
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews elif opt in ("-c", "--consolidation"):
f7c88d61cc1ad2435b0b7cfaedfc9d5248c0be25Automatic Updater consolidation = arg
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews elif opt in ("-w", "--Werror"):
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater Werror = True
bc0a53583d92309bebcf93c408e2f3247ebd3d3cAutomatic Updater
7f94d9a8162c9a96b56e66176702b66e79d8e1a2Automatic Updater incorporations = get_incorporations(repository, publisher, version,
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater static_file)
7f94d9a8162c9a96b56e66176702b66e79d8e1a2Automatic Updater
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater for incorporation_name in incorporations.keys():
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater filename = ''
9e3a7b0faf417a10f5f689edf288807b2d5eedc5Brian Wellington if destdir != None:
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater filename = destdir + '/'
7eda3642eea03f1181e41540c7c8791a57759383Automatic Updater filename += os.path.basename(incorporation_name) + '.p5m'
96713299d08c0735c18ebe8772dd2cc1ecd4356aAutomatic Updater
59528addd704f8d5757b54e540520f74e588a7c7Automatic Updater print("Writing %s manifest to %s" % (incorporation_name, filename))
ce9cad6bb04869c5e94d9dc721032b25117f9210Automatic Updater fd = open(filename, "w+")
7eda3642eea03f1181e41540c7c8791a57759383Automatic Updater fd.write(str(incorporations[incorporation_name]))
00be0f9f61d4c6bf197d000bfa1a6b7e70ea0866Automatic Updater fd.close()
91216cff91b34c9ff6e846dc23f248219cafe660Andreas Gustafsson
00be0f9f61d4c6bf197d000bfa1a6b7e70ea0866Automatic Updaterif __name__ == "__main__":
361bec4bdec45042897fb479b7071cd05bbd56b9Automatic Updater main_func()
9513a2a6670951f5cf5477fcfec9f933fcaff628Automatic Updater