| … | |
… | |
| 3 | # This source code is distributed under the terms of version 2 of the GNU |
3 | # This source code is distributed under the terms of version 2 of the GNU |
| 4 | # General Public License as published by the Free Software Foundation, a copy |
4 | # General Public License as published by the Free Software Foundation, a copy |
| 5 | # of which can be found in the main directory of this project. |
5 | # of which can be found in the main directory of this project. |
| 6 | Gentoo Linux Installer |
6 | Gentoo Linux Installer |
| 7 | |
7 | |
| 8 | $Id: GLIPortage.py,v 1.1 2005/12/23 21:14:08 agaffney Exp $ |
8 | $Id: GLIPortage.py,v 1.2 2005/12/23 22:32:57 agaffney Exp $ |
| 9 | """ |
9 | """ |
| 10 | |
10 | |
| 11 | import os |
11 | import os |
|
|
12 | import re |
| 12 | import GLIUtility |
13 | import GLIUtility |
| 13 | |
14 | |
| 14 | class MissingPackagesError(Exception): |
15 | class MissingPackagesError(Exception): |
| 15 | pass |
16 | pass |
| 16 | |
17 | |
| … | |
… | |
| 53 | important_node = node |
54 | important_node = node |
| 54 | return important_node |
55 | return important_node |
| 55 | |
56 | |
| 56 | class GLIPortage(object): |
57 | class GLIPortage(object): |
| 57 | |
58 | |
| 58 | def __init__(self, chroot_dir): |
59 | def __init__(self, chroot_dir, logger, debug): |
| 59 | os.environ['ROOT'] = chroot_dir |
60 | os.environ['ROOT'] = chroot_dir |
| 60 | import portage, portage_dep |
61 | import portage, portage_dep |
| 61 | self.vdb = portage.db["/"]["vartree"].dbapi |
62 | self.vdb = portage.db["/"]["vartree"].dbapi |
|
|
63 | self.tree = portage.db[chroot_dir]["porttree"].dbapi |
| 62 | self.chroot_dir = chroot_dir |
64 | self._chroot_dir = chroot_dir |
|
|
65 | self._logger = logger |
|
|
66 | self._debug = debug |
| 63 | |
67 | |
| 64 | def resolve_deps(self, dep_list): |
68 | def resolve_deps(self, dep_list): |
| 65 | if dep_list and dep_list[0] == "||": |
69 | if dep_list and dep_list[0] == "||": |
| 66 | for dep in dep_list[1:]: |
70 | for dep in dep_list[1:]: |
| 67 | if isinstance(dep, list): |
71 | if isinstance(dep, list): |
| … | |
… | |
| 115 | graph.remove(pkg) |
119 | graph.remove(pkg) |
| 116 | |
120 | |
| 117 | def get_deps(self, pkgs, grp_install): |
121 | def get_deps(self, pkgs, grp_install): |
| 118 | if not grp_install: |
122 | if not grp_install: |
| 119 | del(os.environ['ROOT']) |
123 | del(os.environ['ROOT']) |
| 120 | return GLIUtility.spawn("emerge -p " + pkgs + r" | grep -e '^\[[a-z]' | cut -d ']' -f2 | sed -e 's:^ ::' -e 's: .\+$::'", chroot=self.chroot_dir, return_output=True)[1].split("\n") |
124 | return GLIUtility.spawn("emerge -p " + pkgs + r" | grep -e '^\[[a-z]' | cut -d ']' -f2 | sed -e 's:^ ::' -e 's: .\+$::'", chroot=self._chroot_dir, return_output=True)[1].split("\n") |
| 121 | os.environ['ROOT'] = self.chroot_dir |
125 | os.environ['ROOT'] = self._chroot_dir |
| 122 | else: |
126 | else: |
| 123 | pkglist = [] |
127 | pkglist = [] |
| 124 | graph = depgraph() |
128 | graph = depgraph() |
| 125 | for pkg in pkgs.split(): |
129 | for pkg in pkgs.split(): |
| 126 | if not self.vdb.match(pkg): |
130 | if not self.vdb.match(pkg): |
|
|
131 | self._logger.log("get_deps(): " + pkg + " is not available via GRP...ignoring") |
| 127 | continue |
132 | continue |
| 128 | self.calc_required_pkgs(pkg, graph) |
133 | self.calc_required_pkgs(pkg, graph) |
| 129 | while graph.node_count(): |
134 | while graph.node_count(): |
| 130 | leaf_nodes = graph.leaf_nodes() |
135 | leaf_nodes = graph.leaf_nodes() |
| 131 | if not leaf_nodes: |
136 | if not leaf_nodes: |
| … | |
… | |
| 135 | continue |
140 | continue |
| 136 | pkglist.extend(leaf_nodes) |
141 | pkglist.extend(leaf_nodes) |
| 137 | for node in leaf_nodes: |
142 | for node in leaf_nodes: |
| 138 | graph.remove(node) |
143 | graph.remove(node) |
| 139 | return pkglist |
144 | return pkglist |
|
|
145 | |
|
|
146 | def copy_pkg_to_chroot(self, package): |
|
|
147 | symlinks = { '/bin/': '/mnt/livecd/bin/', '/boot/': '/mnt/livecd/boot/', '/lib/': '/mnt/livecd/lib/', |
|
|
148 | '/opt/': '/mnt/livecd/opt/', '/sbin/': '/mnt/livecd/sbin/', '/usr/': '/mnt/livecd/usr/', |
|
|
149 | '/etc/gconf/': '/usr/livecd/gconf/' } |
|
|
150 | |
|
|
151 | # Copy the vdb entry for the package from the LiveCD to the chroot |
|
|
152 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): copying vdb entry for " + package) |
|
|
153 | if not GLIUtility.exitsuccess(GLIUtility.spawn("mkdir -p " + self._chroot_dir + "/var/db/pkg/" + package + " && cp -a /var/db/pkg/" + package + "/* " + self._chroot_dir + "/var/db/pkg/" + package)): |
|
|
154 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not copy vdb entry for " + package) |
|
|
155 | |
|
|
156 | # Create list of files for tar to work with from CONTENTS file in vdb entry |
|
|
157 | entries = GLIUtility.parse_vdb_contents("/var/db/pkg/" + package + "/CONTENTS") |
|
|
158 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot: files for " + package + ": " + str(entries)) |
|
|
159 | try: |
|
|
160 | tarfiles = open("/tmp/tarfilelist", "w") |
|
|
161 | for entry in entries: |
|
|
162 | parts = entry.split(" ") |
|
|
163 | # Hack for symlink crappiness |
|
|
164 | for symlink in symlinks: |
|
|
165 | if parts[0].startswith(symlink): |
|
|
166 | parts[0] = symlinks[symlink] + parts[0][len(symlink):] |
|
|
167 | tarfiles.write(parts[0] + "\n") |
|
|
168 | tarfiles.close() |
|
|
169 | except: |
|
|
170 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not create filelist for " + package) |
|
|
171 | |
|
|
172 | # Use tar to transfer files into IMAGE directory |
|
|
173 | tmpdir = "/var/tmp/portage" |
|
|
174 | image_dir = tmpdir + "/" + package.split("/")[1] + "/image" |
|
|
175 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running 'mkdir -p " + self._chroot_dir + image_dir + " && tar -c --files-from=/tmp/tarfilelist --no-recursion 2>/dev/null | tar -C " + self._chroot_dir + image_dir + " -x'") |
|
|
176 | if not GLIUtility.exitsuccess(GLIUtility.spawn("mkdir -p " + self._chroot_dir + image_dir + " && tar -c --files-from=/tmp/tarfilelist --no-recursion 2>/dev/null | tar -C " + self._chroot_dir + image_dir + " -x")): |
|
|
177 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute tar for " + package) |
|
|
178 | |
|
|
179 | # More symlink crappiness hacks |
|
|
180 | for symlink in symlinks: |
|
|
181 | if GLIUtility.is_file(self._chroot_dir + image_dir + symlinks[symlink]): |
|
|
182 | # parts[0] = symlinks[symlink] + parts[len(symlink):] |
|
|
183 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): fixing /usr/livecd/gconf/ stuff in " + image_dir + " for " + package) |
|
|
184 | if not GLIUtility.exitsuccess(GLIUtility.spawn("mv " + self._chroot_dir + image_dir + symlinks[symlink] + " " + self._chroot_dir + image_dir + symlink)): |
|
|
185 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not fix /usr/livecd/gconf/ stuff for " + package) |
|
|
186 | |
|
|
187 | # Run pkg_setup |
|
|
188 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running pkg_setup for " + package) |
|
|
189 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env ROOT=" + self._chroot_dir + " PORTAGE_TMPDIR=" + self._chroot_dir + tmpdir + " ebuild " + self._chroot_dir + "/var/db/pkg/" + package + "/*.ebuild setup")): |
|
|
190 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute pkg_setup for " + package) |
|
|
191 | |
|
|
192 | # Run qmerge |
|
|
193 | # if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running qmerge for " + package) |
|
|
194 | # if not GLIUtility.exitsuccess(GLIUtility.spawn("env ROOT=" + self._chroot_dir + " PORTAGE_TMPDIR=" + self._chroot_dir + tmpdir + " ebuild " + self._chroot_dir + "/var/db/pkg/" + package + "/*.ebuild qmerge")): |
|
|
195 | # raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute qmerge for " + package) |
|
|
196 | |
|
|
197 | # Run pkg_preinst |
|
|
198 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running preinst for " + package) |
|
|
199 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env ROOT=" + self._chroot_dir + " PORTAGE_TMPDIR=" + self._chroot_dir + tmpdir + " ebuild " + self._chroot_dir + "/var/db/pkg/" + package + "/*.ebuild preinst")): |
|
|
200 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute preinst for " + package) |
|
|
201 | |
|
|
202 | # Copy files from image_dir to chroot |
|
|
203 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): copying files from " + image_dir + " to / for " + package) |
|
|
204 | if not GLIUtility.exitsuccess(GLIUtility.spawn("cp -a " + self._chroot_dir + image_dir + "/* " + self._chroot_dir)): |
|
|
205 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not copy files from " + image_dir + " to / for " + package) |
|
|
206 | |
|
|
207 | # Run pkg_postinst |
|
|
208 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running postinst for " + package) |
|
|
209 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env ROOT=" + self._chroot_dir + " PORTAGE_TMPDIR=" + self._chroot_dir + tmpdir + " ebuild " + "/var/db/pkg/" + package + "/*.ebuild postinst")): |
|
|
210 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute postinst for " + package) |
|
|
211 | |
|
|
212 | # Remove image_dir |
|
|
213 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): removing + " + image_dir + " for " + package) |
|
|
214 | if not GLIUtility.exitsuccess(GLIUtility.spawn("rm -rf " + self._chroot_dir + image_dir)): |
|
|
215 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not remove + " + image_dir + " for " + package) |
|
|
216 | |
|
|
217 | def add_pkg_to_world(self, package): |
|
|
218 | if package.find("/") == -1: |
|
|
219 | package = GLIUtility.spawn("portageq best_version / " + package, chroot=self._chroot_dir, return_output=True)[1].strip() |
|
|
220 | if not package: return False |
|
|
221 | expr = re.compile('^(.+?)(-\d.+)?$') |
|
|
222 | res = expr.match(package) |
|
|
223 | if res: |
|
|
224 | GLIUtility.spawn("echo " + res.group(1) + " >> " + self._chroot_dir + "/var/lib/portage/world") |
|
|
225 | |
|
|
226 | def get_best_version_vdb(self, package): |
|
|
227 | return portage.best(vdb.match(package)) |
|
|
228 | |
|
|
229 | def get_best_version_tree(self, package): |
|
|
230 | return portage.best(tree.match(package)) |