17 # fields enclosed by brackets "[]" replaced with your own identifying |
17 # fields enclosed by brackets "[]" replaced with your own identifying |
18 # information: Portions Copyright [yyyy] [name of copyright owner] |
18 # information: Portions Copyright [yyyy] [name of copyright owner] |
19 # |
19 # |
20 # CDDL HEADER END |
20 # CDDL HEADER END |
21 # |
21 # |
22 # Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. |
22 # Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. |
23 # |
23 # |
24 # |
24 # |
25 # incorporator - an utility to incorporate packages in a repo |
25 # incorporator - an utility to incorporate packages in a repo |
26 # |
26 # |
27 |
27 |
28 use Getopt::Long; |
28 import subprocess |
|
29 import json |
|
30 import sys |
|
31 import getopt |
|
32 import re |
|
33 import os.path |
29 |
34 |
30 sub enumerate_packages { |
35 Werror = False # set to true to exit with any warning |
31 local ($repository, $publisher, @fmris) = @_; |
|
32 my @packages = (); |
|
33 |
36 |
34 #printf "/usr/bin/pkg list -ng $repository @fmris\n"; |
37 def warning(msg): |
35 open($fp, "-|", "/usr/bin/pkgrepo", "list", "-H", "-s", $repository, |
38 if Werror == True: |
36 "-p", $publisher, @fmris) || |
39 print >>sys.stderr, "ERROR: %s" % msg |
37 die "pkg: $!"; |
40 sys.exit(1) |
38 while (<$fp>) { |
41 else: |
|
42 print >>sys.stderr, "WARNING: %s" % msg |
39 |
43 |
40 # lines should be in the form: |
44 class Incorporation(object): |
41 # publisher package [r|o] version,5.12-branch:timestamp |
45 name = None |
42 # or lines should be in the form: |
46 version = '5.12' |
43 # publisher package [r|o] version-branch:timestamp |
47 packages = {} |
44 if ((/^(\S+)\s+(\S+)\s+\S?\s+([\d.]+),[\d.]+-([\d.]+):.+$/) || |
|
45 (/^(\S+)\s+(\S+)\s+\S?\s+([\d.]+)-([\d.]+):.+$/)) { |
|
46 my ($package) = (); |
|
47 |
48 |
48 $package->{publisher} = $1; |
49 def __init__(self, name, version): |
49 $package->{name} = $2; |
50 self.name = name |
50 $package->{version} = $3; |
51 self.version = version |
51 $package->{branch} = $4; |
52 self.packages = {} |
52 |
53 |
53 if ($package->{name} !~ m/incorporation/) { |
54 def __package_to_str(self, name, version): |
54 push(@packages, $package); |
55 # strip the :timestamp from the version string |
55 } |
56 version = version.split(':', 1)[0] |
56 } else { |
57 # strip the ,{build-release} from the version string |
57 die "error: cannot handle: ", $_; |
58 version = re.sub(",[\d\.]+", "", version) |
58 } |
|
59 } |
|
60 |
59 |
61 #printf "returning %s\n", $_->{name} for (@packages); |
60 return "depend fmri=%s@%s facet.version-lock.%s=true type=incorporate" % (name, version, name) |
62 |
61 |
63 return @packages; |
62 def add_package(self, name, version): |
64 } |
63 self.packages[name] = version |
65 |
64 |
66 sub print_incorporate { |
65 def __str__(self): |
67 local (%package) = @_; |
66 result = """ |
68 my $facet = "facet.version-lock.$package->{name}"; |
67 set name=pkg.fmri value=pkg:/%s@%s |
|
68 set name=info.classification value="org.opensolaris.category.2008:Meta Packages/Incorporations" |
|
69 set name=org.opensolaris.consolidation value=userland |
|
70 set name=pkg.depend.install-hold value=core-os.userland |
|
71 set name=pkg.summary value="userland consolidation incorporation (%s)" |
|
72 set name=pkg.description value="This incorporation constrains packages from the userland consolidation" |
|
73 """ % (self.name, self.version, self.name) |
69 |
74 |
70 printf "depend fmri=%s@%s-%s %s=true type=incorporate\n", |
75 names = self.packages.keys() |
71 $package->{name}, $package->{version}, $package->{branch}, |
76 names.sort() |
72 $facet; |
77 for name in names: |
73 } |
78 result += (self.__package_to_str(name, self.packages[name]) + '\n') |
74 |
79 |
75 my ($repository, $fmri, $summary, $description, $consolidation) = (); |
80 return result |
76 my %seen = (); |
|
77 |
|
78 $consolidation = 'userland'; |
|
79 |
|
80 GetOptions("R|repository=s" => \$repository, "v|version=s" => \$version, |
|
81 "s|summary=s" => \$summary, "d|description=s" => \$description, |
|
82 "p|package=s" => \$fmri, "f|fmri=s" => \@fmris, |
|
83 "c|consolidation=s" => \$consolidation); |
|
84 |
81 |
85 # |
82 # |
86 # print the incorporation |
83 # This should probably use the pkg APIs at some point, but this appears to be |
|
84 # a stable and less complicated interface to gathering information from the |
|
85 # manifests in the package repo. |
87 # |
86 # |
88 printf "set name=pkg.fmri value=%s\n", $fmri; |
87 def get_incorporations(repository, publisher, inc_version='5.12'): |
89 printf "set name=pkg.summary value='%s'\n", $summary; |
88 tmp = subprocess.Popen(["/usr/bin/pkgrepo", "list", "-F", "json", |
90 printf "set name=pkg.description value='%s'\n", $description; |
89 "-s", repository, |
91 printf "set name=org.opensolaris.consolidation value=%s\n", |
90 "-p", publisher], |
92 $consolidation; |
91 stdout=subprocess.PIPE) |
93 printf "set name=pkg.depend.install-hold value=core-os.%s\n", |
92 incorporations = {} |
94 $consolidation; |
93 packages = json.load(tmp.stdout) |
95 printf "set name=info.classification value='org.opensolaris.category.2008:Meta Packages/Incorporations'\n"; |
|
96 |
94 |
97 @packages = enumerate_packages($repository, $consolidation, @fmris); |
95 # Check for multiple versions of packages in the repo, but keep track of |
|
96 # the latest one. |
|
97 versions = {} |
|
98 for package in packages: |
|
99 pkg_name = package['name'] |
|
100 pkg_version = package['version'] |
98 |
101 |
99 for (@packages) { |
102 if pkg_name in versions: |
100 if ($seen->{$_->{name}} == 1) { |
103 warning("%s is in the repo at multiple versions (%s, %s)" % (pkg_name, pkg_version, versions[pkg_name])) |
101 die "error: duplicate package ", $_->{name}; |
104 pkg_version = max(pkg_version, versions[pkg_name]) |
102 } |
105 versions[pkg_name] = pkg_version |
103 printf "depend fmri=pkg:/%s@%s-%s %s=true type=incorporate\n", |
106 |
104 $_->{name}, $_->{version}, $_->{branch}, |
107 for package in packages: |
105 "facet.version-lock.".$_->{name}; |
108 pkg_name = package['name'] |
106 $seen->{$_->{name}} = 1; |
109 pkg_version = package['version'] |
107 } |
110 |
|
111 # skip older packages and those that don't want to be incorporated |
|
112 if 'pkg.tmp.incorporate' not in package or pkg_version != versions[pkg_name]: |
|
113 continue |
|
114 |
|
115 # a dict inside a list inside a dict |
|
116 incorporate = package['pkg.tmp.incorporate'][0]['value'] |
|
117 |
|
118 for inc_name in incorporate: |
|
119 # if we haven't started to build this incorporation, create one. |
|
120 if inc_name not in incorporations: |
|
121 incorporations[inc_name] = Incorporation(inc_name, inc_version) |
|
122 # find the incorporation and add the package |
|
123 tmp = incorporations[inc_name] |
|
124 tmp.add_package(pkg_name, pkg_version) |
|
125 return incorporations |
|
126 |
|
127 def main_func(): |
|
128 global Werror |
|
129 |
|
130 try: |
|
131 opts, pargs = getopt.getopt(sys.argv[1:], "c:s:p:v:d:w", |
|
132 ["repository=", "publisher=", "version=", |
|
133 "consolidation=", "destdir=", "Werror"]) |
|
134 except getopt.GetoptError, e: |
|
135 usage(_("illegal option: %s") % e.opt) |
|
136 |
|
137 repository = None |
|
138 publisher = None |
|
139 version = None |
|
140 destdir = None |
|
141 consolidation = None |
|
142 |
|
143 for opt, arg in opts: |
|
144 if opt in ("-s", "--repository"): |
|
145 repository = arg |
|
146 elif opt in ("-p", "--publisher"): |
|
147 publisher = arg |
|
148 elif opt in ("-v", "--version"): |
|
149 version = arg |
|
150 elif opt in ("-d", "--destdir"): |
|
151 destdir = arg |
|
152 elif opt in ("-c", "--consolidation"): |
|
153 consolidation = arg |
|
154 elif opt in ("-w", "--Werror"): |
|
155 Werror = True |
|
156 |
|
157 incorporations = get_incorporations(repository, publisher, version) |
|
158 |
|
159 for incorporation_name in incorporations.keys(): |
|
160 filename = '' |
|
161 if destdir != None: |
|
162 filename = destdir + '/' |
|
163 filename += os.path.basename(incorporation_name) + '.p5m' |
|
164 |
|
165 print("Writing %s manifest to %s" % (incorporation_name, filename)) |
|
166 fd = open(filename, "w+") |
|
167 fd.write(str(incorporations[incorporation_name])) |
|
168 fd.close() |
|
169 |
|
170 if __name__ == "__main__": |
|
171 main_func() |