blob: da4112db78cda0aef9ce0cdb29fc5a36aa492ce7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
#!/bin/sh
#
# A bit of hackery to update everything that is humanly possible
# that maybe related to an older version of python. This script can
# be run as many times as you like. It will log the results in
# /tmp/python-updater.log
#
# OLD_PY_VER = old python version we are upgrading from
# NEW_PY_VER = new python version we are upgrading to
# PKGS_EXCEPTIONS = packages that should NOT be re-emerged for any reason
# PKGS_MANUAL = packages that should be re-emerged even if they don't
# fit the criteria (eg. ones that have python compiled
# statically) - FIXME
#
# Runtime Variables:
#
# PKGS_TO_REMERGE = list of packages we deem to need re-emerging
# PKGS_OK = list of packages that should be merged without any problems
# PKGS_MISSING = list of packages that are installed, but cannot be merged
# because they have been pruned from portage
# PKGS_MASKED = list of packages that are installed, but masked.
#
OLD_PY_VER=2.2
NEW_PY_VER=$(python -V 2>&1 | sed 's:Python ::' | cut -d. -f1-2)
PKGS_EXCEPTIONS="dev-lang/python sys-apps/portage"
PKGS_MANUAL="app-office/gnumeric app-office/dia x11-libs/vte"
LOGFILE="/tmp/python-updater.log"
# portage variables
PKG_DBDIR=/var/db/pkg
PORTDIR=`portageq portdir`
PORTDIR_OVERLAYS=`portageq portdir_overlay`
PRETEND=0
PKGS_TO_REMERGE=""
PKGS_COUNT_REMERGE=0
PORTAGE_PYTHON="/usr/bin/python"
# load the gentoo-style info macros, but hack to get around
# it thinking this is an rc script
EBUILD="1"
source /sbin/functions.sh
# misc helper functions
eloginfo() {
einfo $*
DATESTRING=`date +"%Y/%m/%d %H:%M:%S"`
echo "${DATESTRING} - ${*}" >> ${LOGFILE}
}
elogecho() {
echo -n " "
echo $*
DATESTRING=`date +"%Y/%m/%d %H:%M:%S"`
echo "${DATESTRING} - ${*}" >> ${LOGFILE}
}
elogerr() {
eerror $*
DATESTRING=`date +"%Y/%m/%d %H:%M:%S"`
echo "${DATESTRING} ! ${*}" >> ${LOGFILE}
}
elog() {
DATESTRING=`date +"%Y/%m/%d %H:%M:%S"`
echo "${DATESTRING} - ${*}" >> ${LOGFILE}
}
usage() {
echo "usage: python-updater [-h|-p|-o X.X|-n X.X]"
echo " -h help"
echo " -p pretend (don't do anything)"
echo " -o X.X set old python version to upgrade from [default: ${OLD_PY_VER}]"
echo " -n X.X set new python version to upgrade to [default: ${NEW_PY_VER}]"
}
#
# Sanity check
#
if [ -z "${PORTDIR}" ]; then
eerror "Unable to proceed. Can not find PORTDIR. Make sure the command:"
eerror " "
eerror " portageq portdir"
eerror " "
eerror "returns a value. If it doesn't, make sure you have updated to"
eerror "latest portage version."
eerror " "
eerror "Report bugs to http://bugs.gentoo.org/"
exit 1
fi
#
#
# Command Line Parsing
#
#
while [ -n "$1" ]; do
case "$1" in
-h)
usage
exit 0
;;
-p)
PRETEND=1
;;
-o)
shift
OLD_PY_VER="$1"
;;
-n)
shift
NEW_PY_VER="$1"
;;
*)
usage
echo "unrecognised option: $1"
;;
esac
shift
done
#
# Test where portage is, in python2.2 or somewhere else?
#
for py in /usr/bin/python /usr/bin/python${OLD_PY_VER} /usr/bin/python${NEW_PY_VER}; do
if ${py} -c "import portage"; then
PORTAGE_PYTHON=${py}
break;
fi
done
#
#
# Find all packages that have installed something in
# /usr/lib/python${OLD_PY_VER}
#
#
OLD_MODULES_DIR=/usr/lib/python${OLD_PY_VER}
OLD_INCLUDE_DIR=/usr/include/python${OLD_PY_VER}
eloginfo "Starting Python Updater from ${OLD_PY_VER} to ${NEW_PY_VER} :"
eloginfo "Searching for packages with files in ${OLD_MODULES_DIR} .."
# iterate thru all the installed package's contents
for content in `find ${PKG_DBDIR} -name CONTENTS`; do
# extract the category, package name and package version
CATPKGVER=$(echo ${content} | sed "s:${PKG_DBDIR}/\(.*\)/CONTENTS:\1:")
# exclude packages that are an exception, like portage and python itself.
exception=0
for exp in ${PKGS_EXCEPTIONS}; do
if [ -n "$(echo ${CATPKGVER} | grep ${exp})" ]; then
exception=1
break;
fi
done
if [ ${exception} = 1 ]; then
continue;
fi
if fgrep "${OLD_MODULES_DIR}" ${content} > /dev/null; then
PKGS_TO_REMERGE="${PKGS_TO_REMERGE} ${CATPKGVER}"
elogecho "Adding to list: ${CATPKGVER}"
elif fgrep "${OLD_INCLUDE_DIR}" ${content} > /dev/null; then
PKGS_TO_REMERGE="${PKGS_TO_REMERGE} ${CATPKGVER}"
fi
done
# now we have to do each emerge seperately because if an installed version
# does not have the corresponding ebuild in portage, then it will bail.
eloginfo "Calculating Upgrade Package List .."
PKGS_OK=""
PKGS_MASKED=""
PKGS_MISSING=""
MASKED_STRING="been masked"
MISSING_STRING="there are no masked or unmasked ebuilds to satisfy"
for pkg in ${PKGS_TO_REMERGE}; do
emerge_output="$(emerge -p \=$pkg 2>&1)"
if $(echo "${emerge_output}" | grep "${MASKED_STRING}" > /dev/null); then
PKGS_MASKED="${PKGS_MASKED} $pkg"
elogecho "$pkg is masked"
elif $(echo "${emerge_output}" | grep "${MISSING_STRING}" > /dev/null); then
PKGS_MISSING="${PKGS_MISSING} $pkg"
elogecho "$pkg is missing from portage"
else
PKGS_OK="${PKGS_OK} $pkg"
PKGS_COUNT_REMERGE=$((PKGS_COUNT_REMERGE + 1))
fi
done
#
# Use my super dumb package reordering algorithm that works most of the time
#
eloginfo "Re-ordering packages to merge .."
PKGS_OK_SORTED="$(${PORTAGE_PYTHON} ${PORTDIR}/dev-lang/python/files/depreorder.py ${PKGS_OK} | xargs)"
eloginfo "Preparing to merge these packages in this order:"
for pkg in $PKGS_OK_SORTED; do
elogecho "$pkg"
done
# we emerge each package seperately to ensure we know exactly which ones might
# cause an error, and then report it at the end
COUNT=1
PKGS_FAILED=""
if [ "${PRETEND}" != "1" ]; then
for pkg in ${PKGS_OK_SORTED}; do
eloginfo "Starting to merge ($COUNT/$PKGS_COUNT_REMERGE) $pkg .."
if ! emerge --oneshot --nodeps =$pkg; then
PKGS_FAILED="${PKGS_FAILED} $pkg"
elogerr "Failed merging $pkg ($COUNT/$PKGS_COUNT_REMERGE)!"
fi
COUNT=$((COUNT+1))
done
fi
# final output stuff
OUTPUT_PKGS_MASKED=""
for pkg in ${PKGS_MASKED}; do OUTPUT_PKGS_MASKED="${OUTPUT_PKGS_MASKED} \=$pkg"; done
OUTPUT_PKGS_MISSING=""
for pkg in ${PKGS_MISSING}; do OUTPUT_PKGS_MISSING="${OUTPUT_PKGS_MISSING} $pkg"; done
OUTPUT_PKGS_FAILED=""
for pkg in ${PKGS_FAILED}; do OUTPUT_PKGS_FAILED="${OUTPUT_PKGS_FAILED} \=$pkg"; done
if [ -n "${PKGS_FAILED}" -o -n "${PKGS_MISSING}" -o -n "${PKGS_MASKED}" ]; then
echo
ewarn "************************************************************"
ewarn "* Packages that still need to be manually emerged : *"
ewarn "************************************************************"
if [ -n "${OUTPUT_PKGS_MASKED}" ]; then
echo
ewarn " Masked Packages:"
ewarn " ----------------"
ewarn " Unmask the following packages (at your own risk) and "
ewarn " emerge them using this command after removing the '-p'"
ewarn " parameter."
echo
ewarn " emerge -p ${OUTPUT_PKGS_MASKED}"
echo
fi
if [ -n "${OUTPUT_PKGS_MISSING}" ]; then
echo
ewarn " Missing Packages:"
ewarn " -----------------"
ewarn " These packages need to be updated because their versions do"
ewarn " not exist in portage anymore."
echo
for x in ${OUTPUT_PKGS_MISSING}; do
echo " ${x}"
done
fi
if [ -n "${OUTPUT_PKGS_FAILED}" ]; then
echo
ewarn " Failed Packaged:"
ewarn " ----------------"
ewarn " These packages have failed and need to be re-emerged again."
ewarn " Alternatively, try re-running this script again to see if it"
ewarn " can be fixed."
echo
ewarn " emerge -p ${OUTPUT_PKGS_FAILED}"
echo
fi
elog "Python update completed with errors."
elog "Masked Packages:"
for x in ${PKGS_MASKED}; do
elog $x
done
elog "Missing Packages:"
for x in ${PKGS_MISSING}; do
elog $x
done
elog "Failed Packages:"
for x in ${PKGS_FAILED}; do
elog $x
done
elog "Update script completed."
else
eloginfo "Python update completed successfully."
fi
|