/[gli]/branches/qs/src/GLIPortage.py
Gentoo

Contents of /branches/qs/src/GLIPortage.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1307 - (hide annotations) (download) (as text)
Mon Feb 20 17:11:41 2006 UTC (8 years, 10 months ago) by agaffney
Original Path: trunk/src/GLIPortage.py
File MIME type: text/x-python
File size: 16112 byte(s)
len() instead of .length

1 agaffney 1181 """
2     # Copyright 1999-2005 Gentoo Foundation
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
5     # of which can be found in the main directory of this project.
6     Gentoo Linux Installer
7    
8 agaffney 1307 $Id: GLIPortage.py,v 1.44 2006/02/20 17:11:41 agaffney Exp $
9 agaffney 1181 """
10    
11 agaffney 1182 import re
12 agaffney 1216 import os
13 agaffney 1306 import sys
14 agaffney 1181 import GLIUtility
15 agaffney 1204 from GLIException import GLIException
16 agaffney 1181
17     class GLIPortage(object):
18    
19 agaffney 1205 def __init__(self, chroot_dir, grp_install, logger, debug, cc, compile_logfile):
20 agaffney 1182 self._chroot_dir = chroot_dir
21 agaffney 1189 self._grp_install = grp_install
22 agaffney 1182 self._logger = logger
23     self._debug = debug
24 agaffney 1205 self._cc = cc
25     self._compile_logfile = compile_logfile
26 agaffney 1181
27 agaffney 1183 def get_deps(self, pkgs):
28 agaffney 1189 pkglist = []
29     if isinstance(pkgs, str):
30     pkgs = pkgs.split()
31     for pkg in pkgs:
32 agaffney 1305 if not pkg: continue
33 agaffney 1190 if self._debug: self._logger.log("get_deps(): pkg is " + pkg)
34 agaffney 1189 if not self._grp_install or not self.get_best_version_vdb(pkg):
35 agaffney 1190 if self._debug: self._logger.log("get_deps(): grabbing compile deps")
36 agaffney 1208 tmppkglist = GLIUtility.spawn("emerge -p " + pkg + r" 2>/dev/null | grep -e '^\[[a-z]' | cut -d ']' -f2 | sed -e 's:^ ::' -e 's: .\+$::'", chroot=self._chroot_dir, return_output=True)[1].strip().split("\n")
37 agaffney 1189 else:
38 agaffney 1190 if self._debug: self._logger.log("get_deps(): grabbing binary deps")
39 agaffney 1210 # The runtimedeps.py script generates a package install order that is *very* different from emerge itself
40     # tmppkglist = GLIUtility.spawn("python ../../runtimedeps.py " + self._chroot_dir + " " + pkg, return_output=True)[1].strip().split("\n")
41     tmppkglist = []
42 agaffney 1214 for tmppkg in GLIUtility.spawn("emerge -p " + pkg + r" 2>/dev/null | grep -e '^\[[a-z]' | cut -d ']' -f2 | sed -e 's:^ ::' -e 's: .\+$::'", chroot=self._chroot_dir, return_output=True)[1].strip().split("\n"):
43 agaffney 1210 if self._debug: self._logger.log("get_deps(): looking at " + tmppkg)
44 agaffney 1211 if self.get_best_version_vdb("=" + tmppkg):
45 agaffney 1210 if self._debug: self._logger.log("get_deps(): package " + tmppkg + " in host vdb...adding to tmppkglist")
46     tmppkglist.append(tmppkg)
47 agaffney 1190 if self._debug: self._logger.log("get_deps(): deplist for " + pkg + ": " + str(tmppkglist))
48 agaffney 1189 for tmppkg in tmppkglist:
49 agaffney 1192 if self._debug: self._logger.log("get_deps(): checking to see if " + tmppkg + " is already in pkglist")
50 agaffney 1194 if not tmppkg in pkglist and not self.get_best_version_vdb_chroot("=" + tmppkg):
51 agaffney 1192 if self._debug: self._logger.log("get_deps(): adding " + tmppkg + " to pkglist")
52 agaffney 1189 pkglist.append(tmppkg)
53 agaffney 1190 if self._debug: self._logger.log("get_deps(): pkglist is " + str(pkglist))
54 agaffney 1189 return pkglist
55 agaffney 1182
56 agaffney 1221 def parse_vdb_contents(self, file):
57     entries = []
58     try:
59     vdbfile = open(file, "r")
60     except:
61     return entries
62     for line in vdbfile.readlines():
63     parts = line.strip().split(" ")
64     if parts[0] == "obj":
65     entries.append(parts[1])
66 agaffney 1222 # elif parts[0] == "dir":
67     # entries.append(parts[1] + "/")
68 agaffney 1221 elif parts[0] == "sym":
69     entries.append(" ".join(parts[1:4]))
70     entries.sort()
71     return entries
72    
73 agaffney 1280 def copy_pkg_to_chroot(self, package, use_root=False, ignore_missing=False):
74 agaffney 1221 symlinks = { '/bin': '/mnt/livecd/bin/', '/boot': '/mnt/livecd/boot/', '/lib': '/mnt/livecd/lib/',
75     '/opt': '/mnt/livecd/opt/', '/sbin': '/mnt/livecd/sbin/', '/usr': '/mnt/livecd/usr/',
76     '/etc/gconf': '/usr/livecd/gconf/' }
77 agaffney 1182
78 agaffney 1208 tmpdir = "/var/tmp/portage"
79     image_dir = tmpdir + "/" + package.split("/")[1] + "/image"
80 agaffney 1198 root_cmd = ""
81     tmp_chroot_dir = self._chroot_dir
82 agaffney 1204 portage_tmpdir = "/var/tmp/portage"
83 agaffney 1270 vdb_dir = "/var/db/pkg/"
84 agaffney 1198 if use_root:
85     root_cmd = "ROOT=" + self._chroot_dir
86 agaffney 1203 tmp_chroot_dir = ""
87 agaffney 1204 portage_tmpdir = self._chroot_dir + "/var/tmp/portage"
88 agaffney 1270 vdb_dir = self._chroot_dir + "/var/db/pkg/"
89 agaffney 1198
90 agaffney 1280 # Check to see if package is actually in vdb
91     if not GLIUtility.is_file("/var/db/pkg/" + package):
92     if ignore_missing:
93     if self._debug:
94     self._logger.log("DEBUG: copy_pkg_to_chroot(): package " + package + " does not have a vdb entry but ignore_missing=True...ignoring error")
95     return
96     else:
97     raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "There is no vdb entry for " + package)
98    
99 agaffney 1182 # Copy the vdb entry for the package from the LiveCD to the chroot
100     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): copying vdb entry for " + package)
101     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)):
102     raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not copy vdb entry for " + package)
103    
104 agaffney 1208 # Create the image dir in the chroot
105     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running 'mkdir -p " + self._chroot_dir + image_dir + "'")
106     if not GLIUtility.exitsuccess(GLIUtility.spawn("mkdir -p " + self._chroot_dir + image_dir)):
107     raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not create image dir for " + package)
108    
109 agaffney 1182 # Create list of files for tar to work with from CONTENTS file in vdb entry
110 agaffney 1221 entries = self.parse_vdb_contents("/var/db/pkg/" + package + "/CONTENTS")
111 agaffney 1208 if not entries:
112     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): no files for " + package + "...skipping tar and symlink fixup")
113     else:
114     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot: files for " + package + ": " + str(entries))
115     try:
116     tarfiles = open("/tmp/tarfilelist", "w")
117     for entry in entries:
118     parts = entry.split(" ")
119 agaffney 1222 # # Hack for symlink crappiness
120 agaffney 1221 # for symlink in symlinks:
121     # if parts[0].startswith(symlink):
122     # parts[0] = symlinks[symlink] + parts[0][len(symlink):]
123 agaffney 1208 tarfiles.write(parts[0] + "\n")
124     tarfiles.close()
125     except:
126     raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not create filelist for " + package)
127 agaffney 1182
128 agaffney 1208 # Use tar to transfer files into IMAGE directory
129 agaffney 1222 if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running 'tar -cp --files-from=/tmp/tarfilelist --no-recursion 2>/dev/null | tar -C " + self._chroot_dir + image_dir + " -xp'")
130     if not GLIUtility.exitsuccess(GLIUtility.spawn("tar -cp --files-from=/tmp/tarfilelist --no-recursion 2>/dev/null | tar -C " + self._chroot_dir + image_dir + " -xp")):
131 agaffney 1208 raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute tar for " + package)
132 agaffney 1182
133 agaffney 1221 # # More symlink crappiness hacks
134     # for symlink in symlinks:
135     ## if GLIUtility.is_file(self._chroot_dir + image_dir + symlinks[symlink]):
136     # if os.path.islink(self._chroot_dir + image_dir + symlink):
137     # if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): fixing " + symlink + " symlink ickiness stuff in " + image_dir + " for " + package)
138     # GLIUtility.spawn("rm " + self._chroot_dir + image_dir + symlink)
139     # if not GLIUtility.exitsuccess(GLIUtility.spawn("mv " + self._chroot_dir + image_dir + symlinks[symlink] + " " + self._chroot_dir + image_dir + symlink)):
140     # raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not fix " + symlink + " symlink ickiness for " + package)
141 agaffney 1182
142     # Run pkg_setup
143     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running pkg_setup for " + package)
144 agaffney 1269 if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild setup", chroot=tmp_chroot_dir)):
145 agaffney 1182 raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute pkg_setup for " + package)
146    
147     # Run pkg_preinst
148     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running preinst for " + package)
149 agaffney 1269 if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild preinst", chroot=tmp_chroot_dir)):
150 agaffney 1182 raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute preinst for " + package)
151    
152     # Copy files from image_dir to chroot
153 agaffney 1208 if not entries:
154 agaffney 1209 if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): no files for " + package + "...skipping copy from image dir to /")
155 agaffney 1208 else:
156     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): copying files from " + image_dir + " to / for " + package)
157 agaffney 1291 # if not GLIUtility.exitsuccess(GLIUtility.spawn("cp -a " + self._chroot_dir + image_dir + "/* " + self._chroot_dir)):
158     if not GLIUtility.exitsuccess(GLIUtility.spawn("tar -C " + self._chroot_dir + image_dir + "/ -c . | tar -C " + self._chroot_dir + "/ -x")):
159 agaffney 1208 raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not copy files from " + image_dir + " to / for " + package)
160 agaffney 1182
161     # Run pkg_postinst
162     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running postinst for " + package)
163 agaffney 1269 if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild postinst", chroot=tmp_chroot_dir)):
164 agaffney 1182 raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute postinst for " + package)
165    
166     # Remove image_dir
167 agaffney 1208 if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): removing " + image_dir + " for " + package)
168 agaffney 1182 if not GLIUtility.exitsuccess(GLIUtility.spawn("rm -rf " + self._chroot_dir + image_dir)):
169     raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not remove + " + image_dir + " for " + package)
170    
171 agaffney 1297 # Run env-update
172     if not use_root:
173     if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running env-update inside chroot")
174 agaffney 1298 if not GLIUtility.exitsuccess(GLIUtility.spawn("env-update", chroot=self._chroot_dir)):
175 agaffney 1297 raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not run env-update for " + package)
176    
177 agaffney 1182 def add_pkg_to_world(self, package):
178     if package.find("/") == -1:
179 agaffney 1195 package = self.get_best_version_vdb_chroot(package)
180 agaffney 1182 if not package: return False
181 agaffney 1205 expr = re.compile('^=?(.+?/.+?)(-\d.+)?$')
182 agaffney 1182 res = expr.match(package)
183     if res:
184     GLIUtility.spawn("echo " + res.group(1) + " >> " + self._chroot_dir + "/var/lib/portage/world")
185    
186 agaffney 1185 def get_best_version_vdb(self, package):
187 agaffney 1285 if package.startswith('='):
188     package = package[1:]
189     if GLIUtility.is_file("/var/db/pkg/" + package):
190     return package
191 agaffney 1286 else:
192     return ""
193 agaffney 1285 else:
194     return GLIUtility.spawn("portageq best_version / " + package, return_output=True)[1].strip()
195 agaffney 1189
196 agaffney 1194 def get_best_version_vdb_chroot(self, package):
197 agaffney 1287 if package.startswith('='):
198     package = package[1:]
199     if GLIUtility.is_file(self._chroot_dir + "/var/db/pkg/" + package):
200     return package
201     else:
202     return ""
203     else:
204     return GLIUtility.spawn("portageq best_version / " + package, chroot=self._chroot_dir, return_output=True)[1].strip()
205 agaffney 1194
206 agaffney 1184 # def get_best_version_tree(self, package):
207     # return portage.best(tree.match(package))
208 agaffney 1205
209     def emerge(self, packages, add_to_world=True):
210     if isinstance(packages, str):
211     packages = packages.split()
212 agaffney 1223 self._cc.addNotification("progress", (0, "Calculating dependencies for " + " ".join(packages)))
213 agaffney 1205 pkglist = self.get_deps(packages)
214     if self._debug: self._logger.log("install_packages(): pkglist is " + str(pkglist))
215     for i, pkg in enumerate(pkglist):
216 agaffney 1305 if not pkg: continue
217 agaffney 1205 if self._debug: self._logger.log("install_packages(): processing package " + pkg)
218 agaffney 1208 self._cc.addNotification("progress", (float(i) / len(pkglist), "Emerging " + pkg + " (" + str(i+1) + "/" + str(len(pkglist)) + ")"))
219     if not self._grp_install or not self.get_best_version_vdb("=" + pkg):
220 agaffney 1205 status = GLIUtility.spawn("emerge -1 =" + pkg, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True)
221     # status = self._emerge("=" + pkg)
222     if not GLIUtility.exitsuccess(status):
223     raise GLIException("EmergePackageError", "fatal", "emerge", "Could not emerge " + pkg + "!")
224     else:
225     # try:
226     self.copy_pkg_to_chroot(pkg)
227     # except:
228     # raise GLIException("EmergePackageError", "fatal", "emerge", "Could not emerge " + pkg + "!")
229 agaffney 1208 self._cc.addNotification("progress", (float(i+1) / len(pkglist), "Done emerging " + pkg + " (" + str(i+1) + "/" + str(len(pkglist)) + ")"))
230 agaffney 1205 if add_to_world:
231     for package in packages:
232     self.add_pkg_to_world(package)
233 agaffney 1306
234    
235     def usage():
236     print """
237     Usage: GLIPortage.py [-c|--chroot-dir <chroot directory>] [-g|--grp] [-s|--stage3] [-h|--help]
238    
239     Options:
240    
241     -c|--chroot-dir Specifies the directory where your chroot is. This is
242     "/mnt/gentoo" by default.
243    
244     -g|--grp Install specified packages and dependencies into chroot
245     by using files from the LiveCD.
246    
247     -s|--stage3 Create a stage3 equivelant in the chroot directory by using
248     files from the LiveCD.
249    
250     -h|--help Display this help
251     """
252    
253     if __name__ == "__main__":
254     chroot_dir = "/mnt/gentoo"
255     mode = None
256     grp_packages = []
257 agaffney 1307 while len(sys.argv):
258 agaffney 1306 arg = sys.argv.pop(0)
259     if arg == "-c" or arg == "--chroot-dir":
260     chroot_dir = sys.argv.pop(0)
261     elif arg == "-g" or arg == "--grp":
262     mode = "grp"
263     elif arg == "-s" or arg == "--stage3":
264     mode = "stage3"
265     elif arg == "-h" or arg == "--help":
266     usage()
267     sys.exit(0)
268     elif arg[0] == "-":
269     usage()
270     sys.exit(1)
271     else:
272     grp_packages.append(arg)
273    
274     gliportage = GLIPortage(chroot_dir, True, None, False, None, None)
275     if mode == "stage3":
276     if not GLIUtility.is_file("/usr/livecd/systempkgs.txt"):
277     print "Required file /usr/livecd/systempkgs.txt does not exist!"
278     sys.exit(1)
279     try:
280     syspkgs = open("/usr/livecd/systempkgs.txt", "r")
281     systempkgs = syspkgs.readlines()
282     syspkgs.close()
283     except:
284     print "Could not open /usr/livecd/systempkgs.txt!"
285     sys.exit(1)
286    
287     # Pre-create /lib (and possible /lib32 and /lib64)
288     if os.path.islink("/lib") and os.readlink("/lib") == "lib64":
289     if not GLIUtility.exitsuccess(GLIUtility.spawn("mkdir " + chroot_dir + "/lib64 && ln -s lib64 " + chroot_dir + "/lib")):
290     print "Could not precreate /lib64 dir and /lib -> /lib64 symlink"
291     sys.exit(1)
292    
293     syspkglen = len(systempkgs)
294     for i, pkg in enumerate(systempkgs):
295     pkg = pkg.strip()
296     gliportage.copy_pkg_to_chroot(pkg, True, ignore_missing=True)
297     GLIUtility.spawn("cp /etc/make.conf " + chroot_dir + "/etc/make.conf")
298     GLIUtility.spawn("ln -s `readlink /etc/make.profile` " + chroot_dir + "/etc/make.profile")
299     GLIUtility.spawn("cp -f /etc/inittab.old " + chroot_dir + "/etc/inittab")
300    
301     # Nasty, nasty, nasty hack because vapier is a tool
302     for tmpfile in ("/etc/passwd", "/etc/group", "/etc/shadow"):
303     GLIUtility.spawn("grep -ve '^gentoo' " + tmpfile + " > " + chroot_dir + tmpfile)
304    
305     chrootscript = r"""
306     #!/bin/bash
307    
308     source /etc/make.conf
309     export LDPATH="/usr/lib/gcc-lib/${CHOST}/$(cd /usr/lib/gcc-lib/${CHOST} && ls -1 | head -n 1)"
310    
311     ldconfig $LDPATH
312     gcc-config 1
313     env-update
314     source /etc/profile
315     modules-update
316     [ -f /usr/bin/binutils-config ] && binutils-config 1
317     source /etc/profile
318     #mount -t proc none /proc
319     #cd /dev
320     #/sbin/MAKEDEV generic-i386
321     #umount /proc
322     [ -f /lib/udev-state/devices.tar.bz2 ] && tar -C /dev -xjf /lib/udev-state/devices.tar.bz2
323     """
324     script = open(chroot_dir + "/tmp/extrastuff.sh", "w")
325     script.write(chrootscript)
326     script.close()
327     GLIUtility.spawn("chmod 755 /tmp/extrastuff.sh && /tmp/extrastuff.sh", chroot=chroot_dir)
328     GLIUtility.spawn("rm -rf /var/tmp/portage/* /usr/portage /tmp/*", chroot=chroot_dir)
329     print "Stage3 equivelant generation complete!"
330     elif mode == "grp":
331     for pkg in grp_packages:
332     if not gliportage.get_best_version_vdb(pkg):
333     print "Package " + pkg + " is not available for install from the LiveCD"
334     pkglist = gliportage.get_deps(pkg)
335     for tmppkg in pkglist:
336     gliportage.copy_pkg_to_chroot(tmppkg)
337     gliportage.add_pkg_to_world(pkg)
338     print "GRP install complete!"
339     else:
340     print "You must specify an operating mode (-g or -s)!"
341     usage()
342     sys.exit(1)

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20