]> pd.if.org Git - zpackage/blob - zpm-update
add zpm-update
[zpackage] / zpm-update
1 #!/bin/sh
2
3 warn() {
4         echo $* 1>&2
5 }
6
7 run_ldconfig() {
8         if [ $(id -u) -eq 0 ]; then
9                 if [ ! -d $1/etc ]; then
10                         warn "no etc directory in $1, skipping ldconfig"
11                 elif [ -f $1/sbin/ldconfig ]; then
12                         $1/sbin/ldconfig -r ${1:-/}
13                 elif [ -f /sbin/ldconfig ]; then
14                         /sbin/ldconfig -r ${1:-/}
15                 else
16                         true
17                 fi
18         fi
19 }
20
21 changeall() {
22         for pkgid in $(zpm list -s $1); do
23                 zpm pkg $pkgid status=$2
24         done
25 }
26
27 die() {
28         if [ $# -gt 0 ]; then
29                 echo $* 1>&2
30         fi
31         zpm log -i -a 'aborted install' -t "$pkgid" "$*"
32         changeall installing
33         changeall removing installed
34         exit 1
35 }
36
37 current_version() (
38         zpm list -s installed $(zpm parse -n $1)
39 )
40
41 maybe_run() (
42         phase=$1
43         pkgid=$2
44         run=${3:-0}
45         current=$4
46
47         if [ $run -gt 0 ]; then
48                 zpm script -p $phase $pkgid $current
49                 rv=$?
50                 if [ $rv -ne 0 ]; then
51                         warn "$phase script for $pkgid failed"
52                         exit $rv
53                 fi
54         else
55                 if zpm script -Fql -p $phase $pkgid; then
56                         zpm note -e -p $pkgid -m "$phase script not run"
57                 fi
58         fi
59 )
60
61 validity_check() {
62         rv=0
63         # check if we're installing something already
64         var=$(zpm list -s installing | wc -l)
65         if [ $var -gt 0 ]; then
66                 zpm list -v -f $localdb -s installing 
67                 warn "already ($localdb) installing $var package(s)"
68                 rv=1
69         fi
70         var=$(zpm list -s removing | wc -l)
71         if [ $var -gt 0 ]; then
72                 zpm list -v -f $localdb -s removing 
73                 warn "already ($localdb) removing $var package(s)"
74                 rv=1
75         fi
76         var=$(zpm list -s updating | wc -l)
77         if [ $var -gt 0 ]; then
78                 zpm list -v -f $localdb -s updating 
79                 warn "already ($localdb) updating $var package(s)"
80                 rv=1
81         fi
82         if [ $rv -ne 0 ]; then
83                 die "aborting update"
84         fi
85 }
86
87 dryrun=0
88 verbose=0
89 runscripts=1
90 runconfigure=1
91 absorb=0
92 overwrite=0
93 syncopts=''
94
95 packagepath="/var/lib/zpm/packages"
96 to_install=
97 to_remove=
98 to_update=
99 install_for_libs=''
100
101 backup=0
102 ignorelibdeps=0
103 justlist=0
104
105 # TODO option to attempt to resume an ongoing install
106 # zpm-install [-SCn] [ -d localdb ] [ -f pkgfile ] [ -R installroot ] pkgstr ...
107 while getopts f:d:R:nSCvAObBL opt; do
108         case $opt in
109                 f) pkgfile="$OPTARG" ;;
110                 d) localdb="$OPTARG" ;;
111                 P) packagepath="$OPTARG" ;;
112                 D) packagepath="$OPTARG:$packagepath" ;;
113                 R) rootdir="$OPTARG" ;;
114                 S) runscripts=0 ;;
115                 C) runconfigure=0 ;;
116                 A) absorb=1; syncopts="${syncopts} -A" ;;
117                 O) overwrite=1; syncopts="${syncopts} -O" ;;
118                 n) dryrun=1 ;;
119                 v) verbose=1 ;;
120                 b) backup=1 ;;
121                 B) backup=0 ;;
122                 L) ignorelibdeps=1 ;;
123                 l) justlist=1 ;;
124                 *) die "usage ..." ;;
125         esac
126 done
127 shift $(( OPTIND - 1))
128
129 ZPMDB=${localdb:-${ZPMDB:-/var/lib/zpm/local.db}}
130 export ZPMDB
131 # create the localdb if needed
132 zpm init $ZPMDB
133
134 zpm test -v "$ZPMDB" || die "$ZPMDB is not a zpm database"
135
136 validity_check
137
138 for op in "$@"; do
139         case "$op" in
140                 -*) pkgid=$(zpm findpkg -I "${op#-}")
141                         if [ -n "$pkgid" ]; then
142                                 to_remove="$to_remove $pkgid"
143                         fi
144                         # else warn not installed
145                         ;;
146                 +*) pkg=${op#+}
147                         search="$search $pkg"
148                         ;;
149                 *:*) pkg=${op%:*}
150                         file=${op#*:}
151                         pkgid=$(zpm findpkg -f $file $pkg)
152                         if [ -n $pkgid ]; then
153                                 merge="$merge $pkgid:$file"
154                         else
155                                 die "can't find $pkg in $file"
156                         fi
157                         ;;
158                 *) search="$search $op"
159                         ;;
160         esac
161 done
162
163 search=$(echo $search)
164
165 ebail=0
166
167 if [ $ignorelibdeps -eq 1 ]; then
168         merge=$(zpm search -iIO $search)
169 else
170         merge=$(zpm search -iIO -l $search)
171 fi
172
173 if [ $? -ne 0 ]; then
174         warn "unmet packages or dependencies, or errors"
175         exit 1
176 fi
177
178 installset=
179 for mergepkg in $merge; do
180         pkgid=${mergepkg%%:*}
181         installset="$installset $pkgid"
182 done
183 installset=$(printf "%s\n" $installset | sort -u)
184
185 # TODO check for downgrade
186
187 # fixup package
188 nlist=
189 nfound=
190 baddl=
191 for mergepkg in $merge; do
192         pkgid=${mergepkg%:*}
193         repofile=${mergepkg#*:}
194         if [ ${repofile##*.} = 'repo' ]; then
195                 status=$(zpm pkg -f $repofile $pkgid status)
196                 reponame=$(basename $repofile .repo)
197                 if [ "$status" != 'merged' ]; then
198                         repodir=$(dirname $repofile)
199                         zpmfile=$repodir/$reponame/$pkgid.zpm
200                         if [ -f "$zpmfile" ]; then
201                                 nlist="$nlist $pkgid:$zpmfile"
202                                 continue
203                         else
204                                 echo downloading $zpmfile
205                                 zpm repo fetch $reponame $pkgid
206                                 if [ -f "$zpmfile" ]; then
207                                         nlist="$nlist $pkgid:$zpmfile"
208                                 else
209                                         baddl="$baddl $reponame:$pkgid"
210                                 fi
211                         fi
212                 fi
213         else
214                 nlist="$nlist $mergepkg"
215         fi
216 done
217 merge=${nlist#' '}
218 baddl=${baddl#' '}
219
220 if [ -n "$baddl" ]; then
221         printf 'unable to download: %s\n' $baddl
222         die
223 fi
224
225 if [ $justlist -eq 1 ]; then
226         for package in $merge; do
227                 pkgid=${package%:*}
228                 printf 'install %s\n' $pkgid
229         done
230         for pkgid in $to_remove; do
231                 printf 'remove %s\n' $pkgid
232         done
233 fi
234
235 if [ -z "$merge" ] && [ -z "$to_remove" ]; then
236         echo nothing to do
237         exit 0
238 fi
239
240 echo "merge: $merge"
241
242 # finally, merge everything
243 for mergepkg in $merge; do
244         pkgid=${mergepkg%:*}
245         pkgfile=${mergepkg#*:}
246
247         # we could have found the package already in the localdb
248         # in which case, we don't need to merge it
249         # TODO check for symlinks?
250         if [ $pkgfile != $ZPMDB ]; then
251                 echo merging $pkgfile $pkgid
252                 zpm merge -Fuv -f "$pkgfile" $pkgid
253         fi
254         to_install="$to_install $pkgid"
255 done
256
257 to_install=${to_install#' '}
258
259 echo "installing: $to_install"
260
261 # absorb anything we're updating or removing, if absorb flag set
262
263 if [ -n "$to_install" ]; then
264         for pkgid in $to_install; do
265                 current=$(current_version $pkgid)
266                 maybe_run pre-install $pkgid $runscripts $current || die
267         done
268 fi
269
270 if [ -n "$to_remove" ]; then
271         for pkgid in $to_remove; do
272                 maybe_run pre-remove $pkgid $runscripts || die
273         done
274 fi
275
276 if [ -n "$to_install" ]; then
277         for pkgid in $to_install; do
278                 zpm pkg $pkgid status=installing
279         done
280 fi
281
282 if [ -n "$to_remove" ]; then
283         for pkgid in $to_remove; do
284                 zpm pkg $pkgid status=removing
285         done
286 fi
287
288 if [ -n "$rootdir" ]; then
289         ZPM_ROOT_DIR=$rootdir
290         export ZPM_ROOT_DIR
291         : rootdir=${rootdir%%/}
292 fi
293
294 if [ $dryrun -gt 0 ]; then
295         runscripts=0 # we don't want to run post scripts on a dry-run
296         syncopts="$syncopts -n"
297 fi
298
299 if [ $verbose -gt 0 ]; then
300         syncopts="${syncopts} -v"
301 else
302         # force -v during development
303         syncopts="${syncopts} -v"
304 fi
305
306 if [ $dryrun -eq 0 ] && [ $backup -eq 1 ]; then
307         true
308         #zpm absorb -s updating
309         #zpm absorb -s removing
310 fi
311
312 zpm syncfs $syncopts || die 'zpm-syncfs failed';
313
314 if [ -n "$to_remove" ]; then
315         for pkgid in $to_remove; do
316                 maybe_run post-remove $pkgid $runscripts
317         done
318 fi
319
320 changeall removing removed
321
322 echo running ldconfig
323 run_ldconfig $rootdir
324
325 if [ -n "$to_install" ]; then
326         for pkgid in $to_install; do
327                 package=$(zpm parse -n $pkgid)
328                 current=$(zpm list -s installed "$package")
329
330                 maybe_run post-install $pkgid $runscripts $current
331
332                 if [ -n "$current" ]; then
333                         zpm pkg $pkgid status=installed :$current status=updated
334                 else
335                         zpm pkg $pkgid status=installed
336                 fi
337
338                 maybe_run configure $pkgid $runconfigure
339         done
340 fi
341 echo install complete