3 # do one thing and do it well
4 # this program installs packages from a package file
5 # by default, it will install the latest version of each package
10 # if package specifiers are given as arguments after the package file
11 # it will only install those packages.
13 # package specifiers are of the form pkg[-ver[-rel]], i.e the
14 # release can be omitted, and the version-release can be omitted.
16 # zpm install -f foo-0.1-1.zpm
17 # zpm install -f foo.zpm foo-0.1
19 # todo: file tag handling
21 # what we need to install a package:
23 # recording repo: where we record what we've done
24 # source: where we get the package and files from
25 # install root: really just a prefix, but thought about differently,
26 # and we might need to do a chroot
27 # package name to install, could be "all" or "all most recent"
28 # but for now, assume only one package in a file?
30 # zpm install [options] <package ...>
32 pkgver=${ZPMPACKAGEVER:-1.0}
33 pkgrel=${ZPMPACKAGEREL:-1}
37 # allocate an install id, perhaps hash package and timestamp
38 # installid=$(echo $(date) $pkglist | zpm hash)
40 # extract pre-scripts and run them
41 # get list of paths to install
42 # for each path, if directory, create and set mode
43 # for each path, create leading directories
44 # extract to something like /var/tmp/.hash, with low perms
45 # only atomic if same filesystem, so use .installid.hash in the
49 # after all the files, extract post scripts and run them
51 # also need to mark package as installing so if it fails part way
52 # through, it can be finished later
53 # probably also want an option to "backup" any packages being upgraded
54 # so it's trivial to downgrade or to revert if the install fails
56 # option for "multipackage" just to let the system know that's what you meant
57 # option to take filenames from stdin
58 # parse package, version, release from file if not given
59 # TODO what's the difference between prefix and pkgroot
60 # need an option to not chown the files
61 # option to install but not merge/track
64 # -R install root, if installing as root, will chroot?
65 # -C no chroot, even if root
68 # -f source repository file
69 # -d local (recording) repository database
70 # -D don't locally record
71 # -t only files matching tags
72 # -T exclude files matching tags
76 while getopts :R:CNXf:d:Dt:T:u:g: opt; do
78 R) pkgroot="$OPTARG" ;;
80 f) pkgfile="$OPTARG" ;;
89 for cf in /etc/zpmrc ~/.zpmrc ./.zpmrc; do
93 : ${ZPMDB:=/var/lib/zpm/db.zpm}
98 printf 'zpm-install:' 1>&2
104 if [ -z "$pkgfile" ]; then
105 # actually, if no pkgfile, get pkgfile from repo
106 # but need to loop over finding package files then
107 # so this program probably needs to be "install from pkgfile"
108 # and a separate one that will loop over a package
109 # spec list and find from repos
110 die "must specify package file"
111 pkgfile="$package-$pkgver-$pkgrel.zpm"
117 if [ $# -gt 0 ]; then
120 pkglist=$(zpm findpkg $pkgfile)
124 zpm shell $pkgfile<<EOS
125 select path from packagefiles
126 where package||'-'||version||'-'||release = '$pkg'
131 # find a repo file for a given package
141 # strip off a trailing release
142 nv=$(printf '%s' "$1" | sed -e 's/-[0-9]\+$//')
143 nv=$(printf '%s' "$nv" | sed -e 's/-[0-9][^-]*$//')
147 # TODO see if we're already installed
148 # if we are, then bail...
151 # how to do an upgrade?
159 # printf "zzz checking %s vs %s\n" "$1" "$2"
160 # printf "zzz checking %s vs %s\n" "$nv" "$ov"
161 zpm shell $ZPMDB<<-EOS
165 printf('%s-%s-%s', NV.package, NV.version, NV.release) = '$1'
170 printf('%s-%s-%s', OV.package, OV.version, OV.release) = '$2'
176 zpm shell $ZPMDB<<-EOS
180 printf('%s-%s-%s', OV.package, OV.version, OV.release) = '$2'
185 printf('%s-%s-%s', NV.package, NV.version, NV.release) = '$1'
192 zpm shell $ZPMDB<<-EOS
195 inner join packagefiles NV
198 printf('%s-%s-%s', NV.package, NV.version, NV.release) = '$1'
200 printf('%s-%s-%s', OV.package, OV.version, OV.release) = '$2'
201 and NV.hash != OV.hash
212 zpm merge $pkgfile $newver
213 zpm pkg $newver status installing
215 newct=$(newfiles "$newver" "$oldver" | wc -l)
218 if [ $newct -gt 0 ]; then
219 newfiles $newver $oldver
220 { newfiles "$newver" "$oldver"; } | xargs zpm ipkgfile ${user+-u $user} ${group+-g $group} -R "$pkgroot" -f $pkgfile -- $nver
223 ct=$(changedfiles $newver $oldver | wc -l)
225 if [ $ct -gt 0 ]; then
226 changedfiles $newver $oldver | xargs zpm ipkgfile ${user+-u $user} ${group+-g $group} -R "$pkgroot" -f $pkgfile -- $pkg
229 ct=$(removedfiles $newver $oldver | wc -l)
231 if [ $ct -gt 0 ]; then
232 removedfiles $newver $oldver | xargs rm
235 zpm pkg $newver status installed
236 zpm pkg $oldver status upgraded
238 zpm shell $ZPMDB<<-EOS
241 printf('%s-%s-%s', package, version, release) = '$oldver';
246 echo conflict check $pkg $pkgfile
249 zpm shell $pkgfile<<-EOS
251 select hash,path from packagefiles
252 where package||'-'||version||'-'||release = '$pkg'
256 } | while read hash path; do
258 if [ -f $rpath ]; then
259 ihash=$(zpm hash $rpath)
260 if [ $ihash != $hash ]; then
261 die $path already exists
263 elif [ -d $rpath ]; then
264 die $path already exists
269 zpm shell $pkgfile<<-EOS
271 select path from packagefiles
272 where package||'-'||version||'-'||release = '$pkg'
276 } | while read hash path; do
278 if [ -f $rpath ]; then
279 die $path already exists
280 elif [ -d $rpath ]; then
281 die $path already exists
282 elif [ -e $rpath ]; then
283 die $path already exists
288 for pkg in $pkglist; do
289 pname=$(pkgname $pkg)
290 curver=$(zpm findpkg $ZPMDB $pname)
291 pkg=$(zpm findpkg $pkgfile $pkg)
294 if [ -n "$curver" ]; then
296 upgrade=$(zpm vercmp $pkg $curver)
300 0) die 'already installed' $curver;;
301 1) do_upgrade $pkg $curver ; exit 0 ;;
302 -1) die 'would be downgrade' $curver '->' $pkg ;;
303 n) printf 'ok to install %s\n' $pkg ;;
306 zpm merge $pkgfile $pkg
307 # TODO find scripts marked as pre-install
310 # TODO if this is an upgrade, run pre-upgrade
311 #if [ $upgrade != 'n' ]; then
315 # TODO get total size of install so we can do a progress bar
318 # add package info to local package db
319 #zpm merge $pkgfile $pkg
321 # check for conflicts
323 conflicts $pkgroot $pkg
325 # mark package in localdb as installing
326 # zpm setmark installing $pkg
327 # install all the files for a package
328 # TODO install directories first in order of path length
329 echo installing $pkglist
330 filecount=$(pathlist | wc -l)
331 echo $filecount files
332 #die 'aborting for test'
334 zpm pkg $pkg status installing
335 pathlist | xargs zpm ipkgfile ${user+-u $user} ${group+-g $group} -R "$pkgroot" -f $pkgfile -- $pkg
337 # TODO find scripts marked as post-install
338 # TODO if this is an upgrade, run post-upgrade
340 # mark as ready for install
341 zpm pkg $pkg status installed
342 #zpm setmark ready $pkg
345 #zpm setmark installed $pkglist