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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1314 - (hide annotations) (download) (as text)
Mon Feb 27 20:35:34 2006 UTC (8 years, 6 months ago) by agaffney
Original Path: trunk/src/GLIPortage.py
File MIME type: text/x-python
File size: 16786 byte(s)
  src/GLIPortage.py:
  copy_pkg_to_chroot() uses compile_output.log for command output

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 1314 $Id: GLIPortage.py,v 1.48 2006/02/27 20:35:34 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 agaffney 1314 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, logfile=self._compile_logfile, append_log=True)):
102 agaffney 1182 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 agaffney 1314 if not GLIUtility.exitsuccess(GLIUtility.spawn("mkdir -p " + self._chroot_dir + image_dir, logfile=self._compile_logfile, append_log=True)):
107 agaffney 1208 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 agaffney 1314 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", logfile=self._compile_logfile, append_log=True)):
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 1314 if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild setup", chroot=tmp_chroot_dir, logfile=self._compile_logfile, append_log=True)):
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 1314 if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild preinst", chroot=tmp_chroot_dir, logfile=self._compile_logfile, append_log=True)):
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 agaffney 1314 if not GLIUtility.exitsuccess(GLIUtility.spawn("tar -C " + self._chroot_dir + image_dir + "/ -c . | tar -C " + self._chroot_dir + "/ -x", logfile=self._compile_logfile, append_log=True)):
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 1314 if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild postinst", chroot=tmp_chroot_dir, logfile=self._compile_logfile, append_log=True)):
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 1314 if not GLIUtility.exitsuccess(GLIUtility.spawn("rm -rf " + self._chroot_dir + image_dir, logfile=self._compile_logfile, append_log=True)):
169 agaffney 1182 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 1314 if not GLIUtility.exitsuccess(GLIUtility.spawn("env-update", chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True)):
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 agaffney 1311 def usage(progname):
236 agaffney 1306 print """
237 agaffney 1311 Usage: %s [-c|--chroot-dir <chroot directory>] [-g|--grp] [-s|--stage3] [-h|--help]
238 agaffney 1306
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 agaffney 1311 """ % (progname)
252 agaffney 1306
253     if __name__ == "__main__":
254     chroot_dir = "/mnt/gentoo"
255     mode = None
256     grp_packages = []
257 agaffney 1311 progname = sys.argv.pop(0)
258 agaffney 1307 while len(sys.argv):
259 agaffney 1306 arg = sys.argv.pop(0)
260     if arg == "-c" or arg == "--chroot-dir":
261     chroot_dir = sys.argv.pop(0)
262     elif arg == "-g" or arg == "--grp":
263     mode = "grp"
264     elif arg == "-s" or arg == "--stage3":
265     mode = "stage3"
266     elif arg == "-h" or arg == "--help":
267 agaffney 1311 usage(progname)
268 agaffney 1306 sys.exit(0)
269     elif arg[0] == "-":
270 agaffney 1311 usage(progname)
271 agaffney 1306 sys.exit(1)
272     else:
273     grp_packages.append(arg)
274    
275     gliportage = GLIPortage(chroot_dir, True, None, False, None, None)
276     if mode == "stage3":
277     if not GLIUtility.is_file("/usr/livecd/systempkgs.txt"):
278     print "Required file /usr/livecd/systempkgs.txt does not exist!"
279     sys.exit(1)
280     try:
281     syspkgs = open("/usr/livecd/systempkgs.txt", "r")
282     systempkgs = syspkgs.readlines()
283     syspkgs.close()
284     except:
285     print "Could not open /usr/livecd/systempkgs.txt!"
286     sys.exit(1)
287    
288     # Pre-create /lib (and possible /lib32 and /lib64)
289     if os.path.islink("/lib") and os.readlink("/lib") == "lib64":
290     if not GLIUtility.exitsuccess(GLIUtility.spawn("mkdir " + chroot_dir + "/lib64 && ln -s lib64 " + chroot_dir + "/lib")):
291     print "Could not precreate /lib64 dir and /lib -> /lib64 symlink"
292     sys.exit(1)
293    
294     syspkglen = len(systempkgs)
295     for i, pkg in enumerate(systempkgs):
296     pkg = pkg.strip()
297 agaffney 1310 print "Copying " + pkg + " (" + str(i+1) + "/" + str(syspkglen) + ")"
298 agaffney 1306 gliportage.copy_pkg_to_chroot(pkg, True, ignore_missing=True)
299     GLIUtility.spawn("cp /etc/make.conf " + chroot_dir + "/etc/make.conf")
300     GLIUtility.spawn("ln -s `readlink /etc/make.profile` " + chroot_dir + "/etc/make.profile")
301     GLIUtility.spawn("cp -f /etc/inittab.old " + chroot_dir + "/etc/inittab")
302    
303     # Nasty, nasty, nasty hack because vapier is a tool
304     for tmpfile in ("/etc/passwd", "/etc/group", "/etc/shadow"):
305     GLIUtility.spawn("grep -ve '^gentoo' " + tmpfile + " > " + chroot_dir + tmpfile)
306    
307     chrootscript = r"""
308     #!/bin/bash
309    
310     source /etc/make.conf
311     export LDPATH="/usr/lib/gcc-lib/${CHOST}/$(cd /usr/lib/gcc-lib/${CHOST} && ls -1 | head -n 1)"
312    
313     ldconfig $LDPATH
314     gcc-config 1
315     env-update
316     source /etc/profile
317     modules-update
318     [ -f /usr/bin/binutils-config ] && binutils-config 1
319     source /etc/profile
320     #mount -t proc none /proc
321     #cd /dev
322     #/sbin/MAKEDEV generic-i386
323     #umount /proc
324     [ -f /lib/udev-state/devices.tar.bz2 ] && tar -C /dev -xjf /lib/udev-state/devices.tar.bz2
325     """
326     script = open(chroot_dir + "/tmp/extrastuff.sh", "w")
327     script.write(chrootscript)
328     script.close()
329     GLIUtility.spawn("chmod 755 /tmp/extrastuff.sh && /tmp/extrastuff.sh", chroot=chroot_dir)
330     GLIUtility.spawn("rm -rf /var/tmp/portage/* /usr/portage /tmp/*", chroot=chroot_dir)
331     print "Stage3 equivelant generation complete!"
332     elif mode == "grp":
333     for pkg in grp_packages:
334     if not gliportage.get_best_version_vdb(pkg):
335     print "Package " + pkg + " is not available for install from the LiveCD"
336 agaffney 1311 continue
337 agaffney 1306 pkglist = gliportage.get_deps(pkg)
338 agaffney 1311 for i, tmppkg in enumerate(pkglist):
339     print "Copying " + tmppkg + " (" + str(i+1) + "/" + str(len(pkglist)) + ")"
340 agaffney 1306 gliportage.copy_pkg_to_chroot(tmppkg)
341     gliportage.add_pkg_to_world(pkg)
342     print "GRP install complete!"
343     else:
344     print "You must specify an operating mode (-g or -s)!"
345 agaffney 1311 usage(progname)
346 agaffney 1306 sys.exit(1)

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20