| … | |
… | |
| 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.29 2006/01/03 04:24:49 agaffney Exp $ |
8 | $Id: GLIPortage.py,v 1.40 2006/02/11 17:26:33 agaffney Exp $ |
| 9 | """ |
9 | """ |
| 10 | |
10 | |
| 11 | import re |
11 | import re |
| 12 | import os |
12 | import os |
| 13 | import GLIUtility |
13 | import GLIUtility |
| … | |
… | |
| 49 | if self._debug: self._logger.log("get_deps(): adding " + tmppkg + " to pkglist") |
49 | if self._debug: self._logger.log("get_deps(): adding " + tmppkg + " to pkglist") |
| 50 | pkglist.append(tmppkg) |
50 | pkglist.append(tmppkg) |
| 51 | if self._debug: self._logger.log("get_deps(): pkglist is " + str(pkglist)) |
51 | if self._debug: self._logger.log("get_deps(): pkglist is " + str(pkglist)) |
| 52 | return pkglist |
52 | return pkglist |
| 53 | |
53 | |
|
|
54 | def parse_vdb_contents(self, file): |
|
|
55 | entries = [] |
|
|
56 | try: |
|
|
57 | vdbfile = open(file, "r") |
|
|
58 | except: |
|
|
59 | return entries |
|
|
60 | for line in vdbfile.readlines(): |
|
|
61 | parts = line.strip().split(" ") |
|
|
62 | if parts[0] == "obj": |
|
|
63 | entries.append(parts[1]) |
|
|
64 | # elif parts[0] == "dir": |
|
|
65 | # entries.append(parts[1] + "/") |
|
|
66 | elif parts[0] == "sym": |
|
|
67 | entries.append(" ".join(parts[1:4])) |
|
|
68 | entries.sort() |
|
|
69 | return entries |
|
|
70 | |
| 54 | def copy_pkg_to_chroot(self, package, use_root=False): |
71 | def copy_pkg_to_chroot(self, package, use_root=False, ignore_missing=False): |
| 55 | symlinks = { '/bin/': '/mnt/livecd/bin/', '/boot/': '/mnt/livecd/boot/', '/lib/': '/mnt/livecd/lib/', |
72 | symlinks = { '/bin': '/mnt/livecd/bin/', '/boot': '/mnt/livecd/boot/', '/lib': '/mnt/livecd/lib/', |
| 56 | '/opt/': '/mnt/livecd/opt/', '/sbin/': '/mnt/livecd/sbin/', '/usr/': '/mnt/livecd/usr/', |
73 | '/opt': '/mnt/livecd/opt/', '/sbin': '/mnt/livecd/sbin/', '/usr': '/mnt/livecd/usr/', |
| 57 | '/etc/gconf/': '/usr/livecd/gconf/' } |
74 | '/etc/gconf': '/usr/livecd/gconf/' } |
| 58 | |
75 | |
| 59 | tmpdir = "/var/tmp/portage" |
76 | tmpdir = "/var/tmp/portage" |
| 60 | image_dir = tmpdir + "/" + package.split("/")[1] + "/image" |
77 | image_dir = tmpdir + "/" + package.split("/")[1] + "/image" |
| 61 | root_cmd = "" |
78 | root_cmd = "" |
| 62 | tmp_chroot_dir = self._chroot_dir |
79 | tmp_chroot_dir = self._chroot_dir |
| 63 | portage_tmpdir = "/var/tmp/portage" |
80 | portage_tmpdir = "/var/tmp/portage" |
|
|
81 | vdb_dir = "/var/db/pkg/" |
| 64 | if use_root: |
82 | if use_root: |
| 65 | root_cmd = "ROOT=" + self._chroot_dir |
83 | root_cmd = "ROOT=" + self._chroot_dir |
| 66 | tmp_chroot_dir = "" |
84 | tmp_chroot_dir = "" |
| 67 | portage_tmpdir = self._chroot_dir + "/var/tmp/portage" |
85 | portage_tmpdir = self._chroot_dir + "/var/tmp/portage" |
|
|
86 | vdb_dir = self._chroot_dir + "/var/db/pkg/" |
|
|
87 | |
|
|
88 | # Check to see if package is actually in vdb |
|
|
89 | if not GLIUtility.is_file("/var/db/pkg/" + package): |
|
|
90 | if ignore_missing: |
|
|
91 | if self._debug: |
|
|
92 | self._logger.log("DEBUG: copy_pkg_to_chroot(): package " + package + " does not have a vdb entry but ignore_missing=True...ignoring error") |
|
|
93 | return |
|
|
94 | else: |
|
|
95 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "There is no vdb entry for " + package) |
| 68 | |
96 | |
| 69 | # Copy the vdb entry for the package from the LiveCD to the chroot |
97 | # Copy the vdb entry for the package from the LiveCD to the chroot |
| 70 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): copying vdb entry for " + package) |
98 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): copying vdb entry for " + package) |
| 71 | 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)): |
99 | 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)): |
| 72 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not copy vdb entry for " + package) |
100 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not copy vdb entry for " + package) |
| … | |
… | |
| 75 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running 'mkdir -p " + self._chroot_dir + image_dir + "'") |
103 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running 'mkdir -p " + self._chroot_dir + image_dir + "'") |
| 76 | if not GLIUtility.exitsuccess(GLIUtility.spawn("mkdir -p " + self._chroot_dir + image_dir)): |
104 | if not GLIUtility.exitsuccess(GLIUtility.spawn("mkdir -p " + self._chroot_dir + image_dir)): |
| 77 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not create image dir for " + package) |
105 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not create image dir for " + package) |
| 78 | |
106 | |
| 79 | # Create list of files for tar to work with from CONTENTS file in vdb entry |
107 | # Create list of files for tar to work with from CONTENTS file in vdb entry |
| 80 | entries = GLIUtility.parse_vdb_contents("/var/db/pkg/" + package + "/CONTENTS") |
108 | entries = self.parse_vdb_contents("/var/db/pkg/" + package + "/CONTENTS") |
| 81 | if not entries: |
109 | if not entries: |
| 82 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): no files for " + package + "...skipping tar and symlink fixup") |
110 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): no files for " + package + "...skipping tar and symlink fixup") |
| 83 | else: |
111 | else: |
| 84 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot: files for " + package + ": " + str(entries)) |
112 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot: files for " + package + ": " + str(entries)) |
| 85 | try: |
113 | try: |
| 86 | tarfiles = open("/tmp/tarfilelist", "w") |
114 | tarfiles = open("/tmp/tarfilelist", "w") |
| 87 | for entry in entries: |
115 | for entry in entries: |
| 88 | parts = entry.split(" ") |
116 | parts = entry.split(" ") |
| 89 | # Hack for symlink crappiness |
117 | # # Hack for symlink crappiness |
| 90 | for symlink in symlinks: |
118 | # for symlink in symlinks: |
| 91 | if parts[0].startswith(symlink): |
119 | # if parts[0].startswith(symlink): |
| 92 | parts[0] = symlinks[symlink] + parts[0][len(symlink):] |
120 | # parts[0] = symlinks[symlink] + parts[0][len(symlink):] |
| 93 | tarfiles.write(parts[0] + "\n") |
121 | tarfiles.write(parts[0] + "\n") |
| 94 | tarfiles.close() |
122 | tarfiles.close() |
| 95 | except: |
123 | except: |
| 96 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not create filelist for " + package) |
124 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not create filelist for " + package) |
| 97 | |
125 | |
| 98 | # Use tar to transfer files into IMAGE directory |
126 | # Use tar to transfer files into IMAGE directory |
| 99 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running 'tar -c --files-from=/tmp/tarfilelist --no-recursion 2>/dev/null | tar -C " + self._chroot_dir + image_dir + " -x'") |
127 | 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'") |
| 100 | if not GLIUtility.exitsuccess(GLIUtility.spawn("tar -c --files-from=/tmp/tarfilelist --no-recursion 2>/dev/null | tar -C " + self._chroot_dir + image_dir + " -x")): |
128 | 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")): |
| 101 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute tar for " + package) |
129 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute tar for " + package) |
| 102 | |
130 | |
| 103 | # More symlink crappiness hacks |
131 | # # More symlink crappiness hacks |
| 104 | for symlink in symlinks: |
132 | # for symlink in symlinks: |
| 105 | if GLIUtility.is_file(self._chroot_dir + image_dir + symlinks[symlink]): |
133 | ## if GLIUtility.is_file(self._chroot_dir + image_dir + symlinks[symlink]): |
|
|
134 | # if os.path.islink(self._chroot_dir + image_dir + symlink): |
| 106 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): fixing " + symlink + " symlink ickiness stuff in " + image_dir + " for " + package) |
135 | # if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): fixing " + symlink + " symlink ickiness stuff in " + image_dir + " for " + package) |
| 107 | if os.path.islink(self._chroot_dir + image_dir + symlink): |
136 | # GLIUtility.spawn("rm " + self._chroot_dir + image_dir + symlink) |
| 108 | if not GLIUtiltiy.exitsuccess(GLIUtility.spawn("rm " + self._chroot_dir + image_dir + symlink)): |
|
|
| 109 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not remove symlink " + symlink + " for " + package) |
|
|
| 110 | if not GLIUtility.exitsuccess(GLIUtility.spawn("mv " + self._chroot_dir + image_dir + symlinks[symlink] + " " + self._chroot_dir + image_dir + symlink)): |
137 | # if not GLIUtility.exitsuccess(GLIUtility.spawn("mv " + self._chroot_dir + image_dir + symlinks[symlink] + " " + self._chroot_dir + image_dir + symlink)): |
| 111 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not fix " + symlink + " symlink ickiness for " + package) |
138 | # raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not fix " + symlink + " symlink ickiness for " + package) |
| 112 | |
139 | |
| 113 | # Run pkg_setup |
140 | # Run pkg_setup |
| 114 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running pkg_setup for " + package) |
141 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running pkg_setup for " + package) |
| 115 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild /var/db/pkg/" + package + "/*.ebuild setup", chroot=tmp_chroot_dir)): |
142 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild setup", chroot=tmp_chroot_dir)): |
| 116 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute pkg_setup for " + package) |
143 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute pkg_setup for " + package) |
| 117 | |
144 | |
| 118 | # Run pkg_preinst |
145 | # Run pkg_preinst |
| 119 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running preinst for " + package) |
146 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running preinst for " + package) |
| 120 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild /var/db/pkg/" + package + "/*.ebuild preinst", chroot=tmp_chroot_dir)): |
147 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild preinst", chroot=tmp_chroot_dir)): |
| 121 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute preinst for " + package) |
148 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute preinst for " + package) |
| 122 | |
149 | |
| 123 | # Copy files from image_dir to chroot |
150 | # Copy files from image_dir to chroot |
| 124 | if not entries: |
151 | if not entries: |
| 125 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): no files for " + package + "...skipping copy from image dir to /") |
152 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): no files for " + package + "...skipping copy from image dir to /") |
| 126 | else: |
153 | else: |
| 127 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): copying files from " + image_dir + " to / for " + package) |
154 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): copying files from " + image_dir + " to / for " + package) |
| 128 | if not GLIUtility.exitsuccess(GLIUtility.spawn("cp -a " + self._chroot_dir + image_dir + "/* " + self._chroot_dir)): |
155 | # if not GLIUtility.exitsuccess(GLIUtility.spawn("cp -a " + self._chroot_dir + image_dir + "/* " + self._chroot_dir)): |
|
|
156 | if not GLIUtility.exitsuccess(GLIUtility.spawn("tar -C " + self._chroot_dir + image_dir + "/ -c . | tar -C " + self._chroot_dir + "/ -x")): |
| 129 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not copy files from " + image_dir + " to / for " + package) |
157 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not copy files from " + image_dir + " to / for " + package) |
| 130 | |
158 | |
| 131 | # Run pkg_postinst |
159 | # Run pkg_postinst |
| 132 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running postinst for " + package) |
160 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running postinst for " + package) |
| 133 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild /var/db/pkg/" + package + "/*.ebuild postinst", chroot=tmp_chroot_dir)): |
161 | if not GLIUtility.exitsuccess(GLIUtility.spawn("env " + root_cmd + " PORTAGE_TMPDIR=" + portage_tmpdir + " ebuild " + vdb_dir + package + "/*.ebuild postinst", chroot=tmp_chroot_dir)): |
| 134 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute postinst for " + package) |
162 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not execute postinst for " + package) |
| 135 | |
163 | |
| 136 | # Remove image_dir |
164 | # Remove image_dir |
| 137 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): removing " + image_dir + " for " + package) |
165 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): removing " + image_dir + " for " + package) |
| 138 | if not GLIUtility.exitsuccess(GLIUtility.spawn("rm -rf " + self._chroot_dir + image_dir)): |
166 | if not GLIUtility.exitsuccess(GLIUtility.spawn("rm -rf " + self._chroot_dir + image_dir)): |
| 139 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not remove + " + image_dir + " for " + package) |
167 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not remove + " + image_dir + " for " + package) |
|
|
168 | |
|
|
169 | # Run env-update |
|
|
170 | if not use_root: |
|
|
171 | if self._debug: self._logger.log("DEBUG: copy_pkg_to_chroot(): running env-update inside chroot") |
|
|
172 | if not GLIUtility.exitstatus(GLIUtility.spawn("env-update", chroot=self._chroot_dir)): |
|
|
173 | raise GLIException("CopyPackageToChrootError", 'fatal', 'copy_pkg_to_chroot', "Could not run env-update for " + package) |
| 140 | |
174 | |
| 141 | def add_pkg_to_world(self, package): |
175 | def add_pkg_to_world(self, package): |
| 142 | if package.find("/") == -1: |
176 | if package.find("/") == -1: |
| 143 | package = self.get_best_version_vdb_chroot(package) |
177 | package = self.get_best_version_vdb_chroot(package) |
| 144 | if not package: return False |
178 | if not package: return False |
| … | |
… | |
| 146 | res = expr.match(package) |
180 | res = expr.match(package) |
| 147 | if res: |
181 | if res: |
| 148 | GLIUtility.spawn("echo " + res.group(1) + " >> " + self._chroot_dir + "/var/lib/portage/world") |
182 | GLIUtility.spawn("echo " + res.group(1) + " >> " + self._chroot_dir + "/var/lib/portage/world") |
| 149 | |
183 | |
| 150 | def get_best_version_vdb(self, package): |
184 | def get_best_version_vdb(self, package): |
|
|
185 | if package.startswith('='): |
|
|
186 | package = package[1:] |
|
|
187 | if GLIUtility.is_file("/var/db/pkg/" + package): |
|
|
188 | return package |
|
|
189 | else: |
|
|
190 | return "" |
|
|
191 | else: |
| 151 | return GLIUtility.spawn("portageq best_version / " + package, return_output=True)[1].strip() |
192 | return GLIUtility.spawn("portageq best_version / " + package, return_output=True)[1].strip() |
| 152 | |
193 | |
| 153 | def get_best_version_vdb_chroot(self, package): |
194 | def get_best_version_vdb_chroot(self, package): |
|
|
195 | if package.startswith('='): |
|
|
196 | package = package[1:] |
|
|
197 | if GLIUtility.is_file(self._chroot_dir + "/var/db/pkg/" + package): |
|
|
198 | return package |
|
|
199 | else: |
|
|
200 | return "" |
|
|
201 | else: |
| 154 | return GLIUtility.spawn("portageq best_version / " + package, chroot=self._chroot_dir, return_output=True)[1].strip() |
202 | return GLIUtility.spawn("portageq best_version / " + package, chroot=self._chroot_dir, return_output=True)[1].strip() |
| 155 | |
203 | |
| 156 | # def get_best_version_tree(self, package): |
204 | # def get_best_version_tree(self, package): |
| 157 | # return portage.best(tree.match(package)) |
205 | # return portage.best(tree.match(package)) |
| 158 | |
206 | |
| 159 | def emerge(self, packages, add_to_world=True): |
207 | def emerge(self, packages, add_to_world=True): |
| 160 | if isinstance(packages, str): |
208 | if isinstance(packages, str): |
| 161 | packages = packages.split() |
209 | packages = packages.split() |
|
|
210 | self._cc.addNotification("progress", (0, "Calculating dependencies for " + " ".join(packages))) |
| 162 | pkglist = self.get_deps(packages) |
211 | pkglist = self.get_deps(packages) |
| 163 | if self._debug: self._logger.log("install_packages(): pkglist is " + str(pkglist)) |
212 | if self._debug: self._logger.log("install_packages(): pkglist is " + str(pkglist)) |
| 164 | for i, pkg in enumerate(pkglist): |
213 | for i, pkg in enumerate(pkglist): |
| 165 | if self._debug: self._logger.log("install_packages(): processing package " + pkg) |
214 | if self._debug: self._logger.log("install_packages(): processing package " + pkg) |
| 166 | self._cc.addNotification("progress", (float(i) / len(pkglist), "Emerging " + pkg + " (" + str(i+1) + "/" + str(len(pkglist)) + ")")) |
215 | self._cc.addNotification("progress", (float(i) / len(pkglist), "Emerging " + pkg + " (" + str(i+1) + "/" + str(len(pkglist)) + ")")) |