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