]> pd.if.org Git - zpackage/blob - zpm-update
switch to blake2
[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 pullrepos=1
106
107 # treat un-adorned packages as uninstalls
108 uninstall=0
109
110 # TODO option to attempt to resume an ongoing install
111 # zpm-install [-SCn] [ -d localdb ] [ -f pkgfile ] [ -R installroot ] pkgstr ...
112 while getopts f:d:R:nSCvAObBLUzpl opt; do
113         case $opt in
114                 f) pkgfile="$OPTARG" ;;
115                 d) localdb="$OPTARG" ;;
116                 P) packagepath="$OPTARG" ;;
117                 D) packagepath="$OPTARG:$packagepath" ;;
118                 R) rootdir="$OPTARG" ;;
119                 S) runscripts=0 ;;
120                 C) runconfigure=0 ;;
121                 A) absorb=1; syncopts="${syncopts} -A" ;;
122                 O) overwrite=1; syncopts="${syncopts} -O" ;;
123                 n) dryrun=1 ;;
124                 v) verbose=1 ;;
125                 b) backup=1 ;;
126                 B) backup=0 ;;
127                 L) ignorelibdeps=1 ;;
128                 l) justlist=1 ;;
129                 U) uninstall=1 ;;
130                 z) pullrepos=0 ;;
131                 p) syncopts="$syncopts -p" ;;
132                 *) die "usage ..." ;;
133         esac
134 done
135 shift $(( OPTIND - 1 ))
136
137 if [ -n "$rootdir" ]; then
138         : rootdir=${rootdir%%/}
139         ZPM_ROOT_DIR=$rootdir
140         export ZPM_ROOT_DIR
141 fi
142
143 if [ -n "$localdb" ]; then
144         ZPMDB=$localdb
145 elif [ -z "$ZPMDB" ]; then
146         ZPMDB="$ZPM_ROOT_DIR/var/lib/zpm/local.db"
147 fi
148
149 export ZPMDB
150
151 # create the localdb if needed
152 zpm init $ZPMDB
153
154 zpm test -v "$ZPMDB" || die "$ZPMDB is not a zpm database"
155
156 validity_check
157
158 for op in "$@"; do
159         case "$op" in
160                 -*) pkgid=$(zpm findpkg -I "${op#-}")
161                         if [ -n "$pkgid" ]; then
162                                 to_remove="$to_remove $pkgid"
163                         else
164                                 die "$op not installed"
165                         fi
166                         ;;
167                 +*) pkg=${op#+}
168                         search="$search $pkg"
169                         ;;
170                 *:*) pkg=${op%:*}
171                         file=${op#*:}
172                         pkgid=$(zpm findpkg -f $file $pkg)
173                         if [ -n $pkgid ]; then
174                                 merge="$merge $pkgid:$file"
175                         else
176                                 die "can't find $pkg in $file"
177                         fi
178                         ;;
179                 *)
180                         if [ $uninstall -eq 0 ]; then
181                                 search="$search $op"
182                         else
183                                 pkgid=$(zpm findpkg -I "${op}")
184                                 if [ -n "$pkgid" ]; then
185                                         to_remove="$to_remove $pkgid"
186                                 else
187                                         die "$op not installed"
188                                 fi
189                         fi
190                         ;;
191         esac
192 done
193
194 search=$(echo $search)
195
196 ebail=0
197
198 if [ $pullrepos -eq 1 ]; then
199         echo pulling repos
200         zpm repo pull
201 fi
202
203 if [ $ignorelibdeps -eq 1 ]; then
204         merge=$(zpm search -iIO $search)
205         # TODO search for libs anyway and put a note for non-installed
206         # library deps
207 else
208         merge=$(zpm search -iIO -l $search)
209 fi
210
211 if [ $? -ne 0 ]; then
212         warn "unmet packages or dependencies, or errors"
213         exit 1
214 fi
215
216 installset=
217 for mergepkg in $merge; do
218         pkgid=${mergepkg%%:*}
219         installset="$installset $pkgid"
220 done
221 installset=$(printf "%s\n" $installset | sort -u)
222
223 # TODO check for downgrade
224
225 # fixup package
226 nlist=
227 nfound=
228 baddl=
229 for mergepkg in $merge; do
230         pkgid=${mergepkg%:*}
231         repofile=${mergepkg#*:}
232         if [ ${repofile##*.} = 'repo' ]; then
233                 status=$(zpm pkg -f $repofile $pkgid status)
234                 reponame=$(basename $repofile .repo)
235                 if [ "$status" != 'merged' ]; then
236                         repodir=$(dirname $repofile)
237                         zpmfile=$repodir/$reponame/$pkgid.zpm
238                         if [ -f "$zpmfile" ]; then
239                                 nlist="$nlist $pkgid:$zpmfile"
240                                 continue
241                         else
242                                 zpm repo fetch $reponame $pkgid
243                                 if [ -f "$zpmfile" ]; then
244                                         nlist="$nlist $pkgid:$zpmfile"
245                                 else
246                                         baddl="$baddl $reponame:$pkgid"
247                                 fi
248                         fi
249                 fi
250         else
251                 nlist="$nlist $mergepkg"
252         fi
253 done
254 merge=${nlist#' '}
255 baddl=${baddl#' '}
256
257 if [ -n "$baddl" ]; then
258         printf 'unable to download: %s\n' $baddl
259         die
260 fi
261
262 for package in $merge; do
263         pkgid=${package%:*}
264         installlist="$installlist $pkgid"
265 done
266 installlist=${installlist#' '}
267
268 if [ $justlist -eq 1 ]; then
269         for package in $merge; do
270                 pkgid=${package%:*}
271                 printf 'install %s\n' $pkgid
272         done
273         for pkgid in $to_remove; do
274                 printf 'remove %s\n' $pkgid
275         done
276         exit 0
277 fi
278
279 if [ -z "$merge" ] && [ -z "$to_remove" ]; then
280         echo nothing to do
281         exit 0
282 fi
283
284 test -n "$merge" && echo "install: $installlist"
285 test -n "$to_remove" && echo "remove: $to_remove"
286
287 # finally, merge everything
288 for mergepkg in $merge; do
289         pkgid=${mergepkg%:*}
290         pkgfile=${mergepkg#*:}
291
292         # we could have found the package already in the localdb
293         # in which case, we don't need to merge it
294         # TODO check for symlinks?
295         if [ $pkgfile != $ZPMDB ]; then
296                 echo merging $pkgfile $pkgid
297                 zpm merge -Fu -f "$pkgfile" $pkgid
298                 if [ $? -ne 0 ]; then
299                         die "unable to merge $pkgfile"
300                 fi
301         fi
302         to_install="$to_install $pkgid"
303 done
304
305 to_install=${to_install#' '}
306
307 if [ -n "$to_install" ]; then
308         echo "installing: $to_install"
309 fi
310
311 # absorb anything we're updating or removing, if absorb flag set
312
313 if [ -n "$to_install" ]; then
314         for pkgid in $to_install; do
315                 current=$(current_version $pkgid)
316                 maybe_run pre-install $pkgid $runscripts $current || die
317         done
318 fi
319
320 if [ -n "$to_remove" ]; then
321         for pkgid in $to_remove; do
322                 maybe_run pre-remove $pkgid $runscripts || die
323         done
324 fi
325
326 if [ -n "$to_install" ]; then
327         for pkgid in $to_install; do
328                 zpm pkg $pkgid status=installing
329         done
330         zpm shell "$ZPMDB" "update packages set status='updating' where status='installed' and package in (select package from packages where status = 'installing')"
331 fi
332
333 if [ -n "$to_remove" ]; then
334         for pkgid in $to_remove; do
335                 zpm pkg $pkgid status=removing
336         done
337 fi
338
339 if [ $dryrun -gt 0 ]; then
340         runscripts=0 # we don't want to run post scripts on a dry-run
341         syncopts="$syncopts -n"
342 fi
343
344 if [ $verbose -gt 0 ]; then
345         syncopts="${syncopts} -v"
346 fi
347 #else
348         # force -v during development
349         #syncopts="${syncopts} -v"
350 #fi
351
352 if [ $dryrun -eq 0 ] && [ $backup -eq 1 ]; then
353         true
354         #zpm absorb -s updating
355         #zpm absorb -s removing
356 fi
357
358 zpm syncfs $syncopts || die 'zpm-syncfs failed';
359
360 if [ -n "$to_remove" ]; then
361         for pkgid in $to_remove; do
362                 maybe_run post-remove $pkgid $runscripts
363         done
364 fi
365
366 changeall removing removed
367 changeall updating updated
368
369 echo running ldconfig
370 run_ldconfig $rootdir
371
372 if [ -n "$to_install" ]; then
373         for pkgid in $to_install; do
374                 package=$(zpm parse -n $pkgid)
375                 current=$(zpm list -s installed "$package")
376
377                 maybe_run post-install $pkgid $runscripts $current
378
379                 if [ -n "$current" ]; then
380                         zpm pkg $pkgid status=installed :$current status=updated
381                 else
382                         zpm pkg $pkgid status=installed
383                 fi
384
385                 maybe_run configure $pkgid $runconfigure
386         done
387 fi
388 echo install complete