1 |
Author: zmedico |
2 |
Date: 2008-06-03 02:24:40 +0000 (Tue, 03 Jun 2008) |
3 |
New Revision: 10547 |
4 |
|
5 |
Modified: |
6 |
main/trunk/man/make.conf.5 |
7 |
main/trunk/pym/portage/__init__.py |
8 |
Log: |
9 |
Add support for a PORTAGE_RO_DISTDIRS variable. When a given file does not |
10 |
exist in DISTDIR, search for the file in this list of directories. Search |
11 |
order is from left to right. Note that the current implementation works by |
12 |
creating a symlink inside DISTDIR, but that may change in the future. |
13 |
|
14 |
|
15 |
Modified: main/trunk/man/make.conf.5 |
16 |
=================================================================== |
17 |
--- main/trunk/man/make.conf.5 2008-06-03 01:41:09 UTC (rev 10546) |
18 |
+++ main/trunk/man/make.conf.5 2008-06-03 02:24:40 UTC (rev 10547) |
19 |
@@ -451,6 +451,12 @@ |
20 |
it will increment it. For more information about nice levels and what |
21 |
are acceptable ranges, see \fBnice\fR(1). |
22 |
.TP |
23 |
+\fBPORTAGE_RO_DISTDIRS\fR = \fI[space delimited list of directories]\fR |
24 |
+When a given file does not exist in \fBDISTDIR\fR, search for the file |
25 |
+in this list of directories. Search order is from left to right. Note |
26 |
+that the current implementation works by creating a symlink inside |
27 |
+\fBDISTDIR\fR, but that may change in the future. |
28 |
+.TP |
29 |
\fBPORTAGE_RSYNC_INITIAL_TIMEOUT\fR = \fIinteger\fR |
30 |
Used by \fBemerge \-\-sync\fR as a timeout for the initial connection to an |
31 |
rsync server. |
32 |
|
33 |
Modified: main/trunk/pym/portage/__init__.py |
34 |
=================================================================== |
35 |
--- main/trunk/pym/portage/__init__.py 2008-06-03 01:41:09 UTC (rev 10546) |
36 |
+++ main/trunk/pym/portage/__init__.py 2008-06-03 02:24:40 UTC (rev 10547) |
37 |
@@ -988,6 +988,7 @@ |
38 |
"PORTAGE_FETCH_CHECKSUM_TRY_MIRRORS", "PORTAGE_FETCH_RESUME_MIN_SIZE", |
39 |
"PORTAGE_GPG_DIR", |
40 |
"PORTAGE_GPG_KEY", "PORTAGE_PACKAGE_EMPTY_ABORT", |
41 |
+ "PORTAGE_RO_DISTDIRS", |
42 |
"PORTAGE_RSYNC_EXTRA_OPTS", "PORTAGE_RSYNC_OPTS", |
43 |
"PORTAGE_RSYNC_RETRIES", "PORTAGE_USE", "PORT_LOGDIR", |
44 |
"QUICKPKG_DEFAULT_OPTS", |
45 |
@@ -3096,6 +3097,54 @@ |
46 |
os.rename(filename, temp_filename) |
47 |
return temp_filename |
48 |
|
49 |
+def _check_digests(filename, digests): |
50 |
+ """ |
51 |
+ Check digests and displey a message if an error occurs. |
52 |
+ @return True if all digests match, False otherwise. |
53 |
+ """ |
54 |
+ verified_ok, reason = portage.checksum.verify_all(filename, digests) |
55 |
+ if not verified_ok: |
56 |
+ writemsg("!!! Previously fetched" + \ |
57 |
+ " file: '%s'\n" % filename, noiselevel=-1) |
58 |
+ writemsg("!!! Reason: %s\n" % reason[0], |
59 |
+ noiselevel=-1) |
60 |
+ writemsg(("!!! Got: %s\n" + \ |
61 |
+ "!!! Expected: %s\n") % \ |
62 |
+ (reason[1], reason[2]), noiselevel=-1) |
63 |
+ return False |
64 |
+ return True |
65 |
+ |
66 |
+def _check_distfile(filename, digests, eout): |
67 |
+ """ |
68 |
+ @return a tuple of (match, stat_obj) where match is True if filename |
69 |
+ matches all given digests (if any) and stat_obj is a stat result, or |
70 |
+ None if the file does not exist. |
71 |
+ """ |
72 |
+ if digests is None: |
73 |
+ digests = {} |
74 |
+ size = digests.get("size") |
75 |
+ if size is not None and len(digests) == 1: |
76 |
+ digests = None |
77 |
+ |
78 |
+ try: |
79 |
+ st = os.stat(filename) |
80 |
+ except OSError: |
81 |
+ return (False, None) |
82 |
+ if size is not None and size != st.st_size: |
83 |
+ return (False, st) |
84 |
+ if not digests: |
85 |
+ if size is not None: |
86 |
+ eout.ebegin("%s %s ;-)" % (os.path.basename(filename), "size")) |
87 |
+ eout.eend(0) |
88 |
+ else: |
89 |
+ if _check_digests(filename, digests): |
90 |
+ eout.ebegin("%s %s ;-)" % (os.path.basename(filename), |
91 |
+ " ".join(sorted(digests)))) |
92 |
+ eout.eend(0) |
93 |
+ else: |
94 |
+ return (False, st) |
95 |
+ return (True, st) |
96 |
+ |
97 |
_fetch_resume_size_re = re.compile('(^[\d]+)([KMGTPEZY]?$)') |
98 |
|
99 |
_size_suffix_map = { |
100 |
@@ -3229,6 +3278,11 @@ |
101 |
# no digests because fetch was not called for a specific package |
102 |
mydigests = {} |
103 |
|
104 |
+ import shlex |
105 |
+ ro_distdirs = [x for x in \ |
106 |
+ shlex.split(mysettings.get("PORTAGE_RO_DISTDIRS", "")) \ |
107 |
+ if os.path.isdir(x)] |
108 |
+ |
109 |
fsmirrors = [] |
110 |
for x in range(len(mymirrors)-1,-1,-1): |
111 |
if mymirrors[x] and mymirrors[x][0]=='/': |
112 |
@@ -3356,8 +3410,16 @@ |
113 |
1 partially downloaded |
114 |
2 completely downloaded |
115 |
""" |
116 |
+ fetched = 0 |
117 |
+ |
118 |
+ digests = mydigests.get(myfile, {}) |
119 |
+ size = digests.get("size") |
120 |
+ if parallel_fetchonly: |
121 |
+ digests.clear() |
122 |
+ if size is not None: |
123 |
+ digests["size"] = size |
124 |
+ |
125 |
myfile_path = os.path.join(mysettings["DISTDIR"], myfile) |
126 |
- fetched=0 |
127 |
has_space = True |
128 |
file_lock = None |
129 |
if listonly: |
130 |
@@ -3403,6 +3465,75 @@ |
131 |
waiting_msg=waiting_msg) |
132 |
try: |
133 |
if not listonly: |
134 |
+ |
135 |
+ eout = portage.output.EOutput() |
136 |
+ eout.quiet = mysettings.get("PORTAGE_QUIET") == "1" |
137 |
+ match, mystat = _check_distfile(myfile_path, digests, eout) |
138 |
+ if match: |
139 |
+ if can_fetch and not fetch_to_ro: |
140 |
+ try: |
141 |
+ apply_secpass_permissions(myfile_path, |
142 |
+ gid=portage_gid, mode=0664, mask=02, |
143 |
+ stat_cached=mystat) |
144 |
+ except portage.exception.PortageException, e: |
145 |
+ if not os.access(myfile_path, os.R_OK): |
146 |
+ writemsg("!!! Failed to adjust permissions:" + \ |
147 |
+ " %s\n" % str(e), noiselevel=-1) |
148 |
+ del e |
149 |
+ continue |
150 |
+ |
151 |
+ if can_fetch and mystat is None: |
152 |
+ # Remove broken symlinks if necessary. |
153 |
+ try: |
154 |
+ os.unlink(myfile_path) |
155 |
+ except OSError: |
156 |
+ pass |
157 |
+ |
158 |
+ if mystat is not None: |
159 |
+ if mystat.st_size == 0: |
160 |
+ if can_fetch: |
161 |
+ try: |
162 |
+ os.unlink(myfile_path) |
163 |
+ except OSError: |
164 |
+ pass |
165 |
+ elif can_fetch: |
166 |
+ if mystat.st_size < fetch_resume_size and \ |
167 |
+ mystat.st_size < size: |
168 |
+ writemsg((">>> Deleting distfile with size " + \ |
169 |
+ "%d (smaller than " "PORTAGE_FETCH_RESU" + \ |
170 |
+ "ME_MIN_SIZE)\n") % mystat.st_size) |
171 |
+ try: |
172 |
+ os.unlink(myfile_path) |
173 |
+ except OSError, e: |
174 |
+ if e.errno != errno.ENOENT: |
175 |
+ raise |
176 |
+ del e |
177 |
+ elif mystat.st_size >= size: |
178 |
+ temp_filename = \ |
179 |
+ _checksum_failure_temp_file( |
180 |
+ mysettings["DISTDIR"], myfile) |
181 |
+ writemsg_stdout("Refetching... " + \ |
182 |
+ "File renamed to '%s'\n\n" % \ |
183 |
+ temp_filename, noiselevel=-1) |
184 |
+ |
185 |
+ if can_fetch and ro_distdirs: |
186 |
+ readonly_file = None |
187 |
+ for x in ro_distdirs: |
188 |
+ filename = os.path.join(x, myfile) |
189 |
+ match, mystat = _check_distfile(filename, digests, eout) |
190 |
+ if match: |
191 |
+ readonly_file = filename |
192 |
+ break |
193 |
+ if readonly_file is not None: |
194 |
+ try: |
195 |
+ os.unlink(myfile_path) |
196 |
+ except OSError, e: |
197 |
+ if e.errno != errno.ENOENT: |
198 |
+ raise |
199 |
+ del e |
200 |
+ os.symlink(readonly_file, myfile_path) |
201 |
+ continue |
202 |
+ |
203 |
if fsmirrors and not os.path.exists(myfile_path) and has_space: |
204 |
for mydir in fsmirrors: |
205 |
mirror_file = os.path.join(mydir, myfile) |
206 |
|
207 |
-- |
208 |
gentoo-commits@l.g.o mailing list |