Archive old uefi hint
[linux_from_scratch_hints.git] / package_management_using_trip.txt
blob653d5e7340d53776478952cc0bf7445eec4f0eb2
1 AUTHOR: Pierre Hebert <pierrot at 1000wallpapers dot com>
3 DATE: 2006-05-13
5 LICENSE: GNU Free Documentation License Version 1.2
7 SYNOPSIS: TRIP, a TRIvial Packager for LFS (and other linux systems)
9 DESCRIPTION:
10 Trip is a package manager focusing on the LFS users needs : build many, install
11 once. Trip tracks modified files during install, thanks to a simple but 100%
12 reliable mechanism : a combination of unionfs and chroot usage. Trip can be used
13 with no restrictions on other Linux than LFS.
15 PREREQUISITES:
16 This hint requires :
17 - a sufficient knowledge of LinuxFromScratch.
18 - a sufficient knowledge of the linux problematic of package management. I
19 suggest reading among other documents :
20 http://www.linuxfromscratch.org/hints/downloads/files/fakeroot.txt from Tushar
21 Teredesai.
22 - a linux 2.6 system with unionfs >= 1.1.3
23 - root privileges
24 - the desire to experiment somewhat weird stuff.
27 HINT:
29 --------------------------------------------------------------------------------
30 Background
31 --------------------------------------------------------------------------------
32 After having built quite a lot of LFS system I found that a LFS user is faced to
33 a particular package context :
34 - a LFS user install a LOT OF packages
35 - each package is installed once (maybe two...)
36 - a LFS user wants to know what is installed (every added, modified and
37 eventually deleted files)
39 As a LFS user what I want is : 
40 - run "make install" as root, and see what has been done
41 - be able to come back immediately to the state before "make install", as if I
42 didn't execute "make install"
43 - store packages information in a simple database, and eventually be able to
44 uninstall them
46 What I don't want :
47 - complexity
48 - to endlessly patch makefiles and/or sources because of the packaging tool
49 needs
51 Most of the well known package managers like RPM or DPKG do not fill these needs
52 at all. Their aim is to build a package once, and install it often. They are not
53 designed for users like LFS users, because it's not exactly easy to create spec
54 files for example. These sort of package managers require a knowledge of each
55 package in order to be sure not to miss some files. It is especially difficult
56 with packages that are not built with autoconf/automake.
58 Beside that I also notice that there is currently no 100% reliable method to
59 know what files is modified during a "make install" (or other command).
60  * The fakeroot approach doesn't prevent a package to install files where it
61 wants, of course. For example it is easy to confuse a system with a mistake in a
62 RPM spec file.
63  * The LD_PRELOAD mechanism, associated with the overload of some functions like
64 "open", "mkdir", etc seems, at first, to be a solution. I have been using it for
65 a while, with a lot of satisfaction, coupled with RPM and DPKG. You can have a
66 look at Checkinstall (http://asic-linux.com.mx/~izto/checkinstall/) or Paco
67 (http://paco.sourceforge.net/). There are several other projects using
68 LD_PRELOAD.
69 Unfortunately this trick has some limitations, the bigger is to be "blind" with
70 set uid programs. The second is the complexity of the LD_PRELOADed library which
71 is tightly linked to glibc internal mechanisms.
72  * The technique of finding files according to their creation/modification will
73 fail with some packages because some uses "cp -p" for example. So you are never
74 really sure of what have been installed.
76 But in my opinion the biggest problem with these techniques is that once the
77 system has been modified, you may know what has been touched, but you may not be
78 able to come back to the original state.
80 Another package management is the Package Users technique : it is great and
81 really powerfull because it totally prevents any unwanted modification of the
82 system (see
83 http://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.
84 txt). However in my opinion it requires too many work for each package,
85 especially on install targets in makefiles.
87 After all, I wasn't satisfied by existing package managers, even if I am
88 convinced of the interest of each method. So I was looking for another method to
89 track any arbitrary changes on a filesystem, and finally the answer was almost
90 evident : unionfs. The idea is explained in the following paragraph.
92 --------------------------------------------------------------------------------
93 The Idea
94 --------------------------------------------------------------------------------
95 The idea of trip is to use two filesystems in a union filesystem. See
96 http://www.unionfs.org/.
97 One filesystem is the target filesystem on which the user wants to do "make
98 install", and is used READ-ONLY, the second is an empty filesystem merged with
99 the first, and used READ-WRITE.
101 Let's take an example fstab :
102 /dev/hdb1      /mnt/lfs     ext3   defaults                    0    0
103 /dev/hdc1      /mnt/pkg     ext3   defaults                    0    0
104 unionfs        /mnt/union   unionfs dirs=/mnt/pkg:/mnt/lfs=ro  0    0
106 The result of this is :
107 - if we read a file in /mnt/union, it will be read from /mnt/lfs, if it doesn't
108 exists in /mnt/pkg
109 - if we create a file in /mnt/union it will be really created in /mnt/pkg
110 - if we modify a file in /mnt/union belonging to /mnt/lfs it will be copied and
111 modified in /mnt/pkg
112 - if we delete a file in /mnt/union belonging to /mnt/lfs, a special file will
113 be created in /mnt/pkg (whiteout mode)
114 - the overall behaviour of the program executing in /mnt/union is as if there
115 were only one normal filesystem.
117 Hence a chroot in a union filesystem gives these marvelous benefits : 
118 - in no case the /mnt/lfs will be altered
119 - created, deleted and modified files are all stored in /mnt/pkg
120 - all libraries and tools are available in their real prefix, running
121 ./configure --prefix=/usr is possible.
122 It's a bit like magic and this is all we need for trip. Could it be easier to
123 know what has been made by "make install" (or any other command) ?
125 Note that this simple idea could be implemented in other package managers with
126 probably few work.
128 --------------------------------------------------------------------------------
129 Trip history and goals
130 --------------------------------------------------------------------------------
131 Trip was really born under the temporary name of sp, somewhere in late 2005, I
132 don't remember when exactly. SP stands for "Smart Package", where Smart itself
133 stands for "Simple Management of Really Trivial" package. Unfortunately another
134 software was named Smart Package so sp becames trip.
135 At the beginning this was just a simple shell script to test the unionfs method.
136 This script only listed the modified/created/deleted files after a "make
137 install". But soon it finally becames a sufficient package manager that I called
138 "trip".
139 Trip is a trivial package manager because it manages a trivial package format,
140 i.e. gnu tar. Why would we use obscure package formats, since we can use
141 powerfull and simple tools like tar ?
143 Trip is inspired from some RPM base concepts, and also from Pacman (Arch Linux
144 package manager).
146 That is all the short history of trip.
148 At time of writting, trip is a 934 lines bash script, with lots of comments. And
149 I used it to manage about 500 packages from linux-libc-headers to kde.
152 The main goals of trip are :
153 - 100% safe installation
154 - able to package a whole LFS system
155 - be as simple as possible, I fear too complex package managers that need
156 beecrypt, neon and rpm2cpio...
157 - opened : I want to be able to see what is in packages before to install them,
158 modify packages eventually, modify the package database in case of problem.
160 One special goal quoted before is to be "able to package a whole LFS system". In
161 the past I built some LFS, then install RPM or DPKG for example. But the base
162 LFS itself was not packaged, so there was always a dark area that could be
163 altered without problem. Trip is designed to run during the Chapter 6 of LFS,
164 with nothing but /tools and unionfs.
166 At last but not least, trip does not intend to be a replacement of any other
167 package manager. In fact trip does very few things. Its primary goal is perhaps
168 to demonstrate the use of unionfs and chroot together, in order to provide a
169 really strong package management at an uncommonly low cost.
171 --------------------------------------------------------------------------------
172 Trip install
173 --------------------------------------------------------------------------------
174 In this paragraph we explain how to install trip for use later in the Chapter 6
175 of LFS.
177 We assume that we get those filesystems: 
178 /mnt/lfs : LFS system target, $LFS=/mnt/lfs
179 /mnt/pkg : free filesystem in which are put installed files
180 /mnt/union : merge of /mnt/lfs(ro) and /mnt/pkg(rw)
182 * Step 1 : put the trip directory at the root of the target LFS system.
183 (see later for download)
184         cd $LFS && tar xf /foo/bar/trip.tar
185         ln $LFS/trip / (same idea as /tools in fact : trip is available from the
186 same path, chroot or not)
187         export PATH=$PATH:/trip/trip/bin
189 * Step 2 : prepare a second empty file system, with enough space to compile and
190 install the glibc (biggest package in LFS ?). Later you may need more space, for
191 example KDE needs lots of space. I suggest 1 or 2 GB, if you can.
192 Warning : loop devices can't be used safely actually with unionfs.
193 Example :
194         mkfs.ext3 /dev/hdc1
195         mkdir /mnt/pkg
196         echo "/dev/hdc1   /mnt/pkg     ext3   defaults  0  0" >> /etc/fstab
197         mount /mnt/pkg (keep it mounted)
199 * Step 3 : prepare the unionfs filesystem
200 Example :
201         modprobe unionfs
202         echo "unionfs /mnt/union unionfs dirs=/mnt/pkg:/mnt/lfs=ro 0 0" >>
203 /etc/fstab
204         mount /mnt/union && umount /mnt/union (just to see if it works, but
205 don't keep it mounted)
207 * Step 4 : trip configuration
208 For now take the following configuration and put it in /trip/trip/conf/conf:
210 ---------- cut after this line -------------
211 # TRIP configuration file
212 # TRIP is a TRIvial Packager
213 # copyright 2006 Pierre Hebert <pierrot@1000wallpapers.com>
214 # http://things.1000wallpapers.com/
216 # the real root filesystem, in which resides the operating system
217 TRIP_FS_ROOT=/mnt/lfs
219 # the filesystem on which are temporarily created the files during the install
220 phase
221 TRIP_FS_PKG=/mnt/pkg
223 # the union filesystem mergin $TRIP_FS_ROOT(ro) and $TRIP_FS_PKG(rw)
224 TRIP_FS_UNION=/mnt/union
226 # the package repository root
227 TRIP_PKG_ROOT=/trip/lfs-svn-20060416
229 # where to install binary packages
230 TRIP_INSTALL_DIR=/mnt/lfs
232 # the mode tell if we use /tools or / as build environment (hosted = build from
233 /tools, normal=/)
234 TRIP_MODE=hosted
236 # level of activity reporting
237 TRIP_TRACE_LEVEL=3
239 # root location of temporary files
240 TRIP_TMPDIR=/trip/tmp
241 ---------- cut before this line -------------
243 Et voila, trip is ready to go.
244 Now let's see what's in the trip directory and how it works before to continue.
246 --------------------------------------------------------------------------------
247 Trip usage in short
248 --------------------------------------------------------------------------------
249 The common usage of trip is :
250 trip --build /path/to/my/source/trip/package
251 trip --install /path/to/the/binary/package/created
253 trip --wizard (and answer to the question)
256 Trip handles three different inputs, more or less the same way as RPM :
257 - source package directory : a source package directory is structured as bellow:
258         src/ :  contains the .tar.gz archives, eventually some patches or other
259           files.
260         support/ : contains an "identification" file (meta infos), a "build.sh"
261              script (optionnal) and an "install.sh" script. In this "support" 
262              subdirectory we can also optionally find a file "exclude" and 
263              another "include" that list files to systematically exclude or 
264              include from the binary package. Finally in support there may be 
265              four helper scripts called {pre,post}_{,un}install.sh.
267 - source package archive : simply a tar archive of a source package directory.
269 - binary package archive : a tar archive containing all files modified during
270 the execution of the script "install.sh", and the file "identification", that
271 gives meta info about this package, and eventually {pre,post}_{,un}install.sh
272 scripts.
274 The purpose of {pre,post}_{,un}install.sh is to execute some tasks upon the
275 extraction of a binary package, or the uninstallation of the package. For
276 example when installing MySQL, the post_install.sh script will contains
277 something like "/etc/rc.d/init.d/mysql start".
279 The basic work of trip when using "trip --build /path/to/my/source/trip/package"
280 is (simplified) :
281 - read "identification" file from
282 /path/to/my/source/trip/package/support/identification
283 - create a temp directory in which build the package
284 - mount the /mnt/union unionfs filesystem (and virtual filesystems too)
285 - chroot into /mnt/union
286 - execute /path/to/my/source/trip/package/support/build.sh
287 - execute /path/to/my/source/trip/package/support/install.sh
288 - leave chroot from /mnt/union, umount /mnt/union
289 - see what has been modified and stored in /mnt/pkg
290 - create a binary package of those modified files
292 When invoking "trip --install /path/to/the/binary/package/created" :
293 - check file conflicts (basic check)
294 - extract files from the binary archive
295 - store an entry in the package database
297 trip --help gives :
298 + usage : trip --config_dir <dir>
299 +              --install <binary package file>
300 +              --uninstall <package name>
301 +              --rebuild <source package file>
302 +              --build <source package directory>
303 +              --wizard
304 +              --list [<package name>]
305 +              --find-file <file>
306 +              --help
308 Here is a short explanation of these switches :
309 --config_dir : location of trip configuration, normally default value is ok
310 --install : install a binary trip package
311 --uninstall : do what its name means
312 --rebuild : build a binary trip package from a source package
313 --build : build a binary trip package from a source directory
314 --wizard : very useful mode where you are asked some questions, and where a
315 skeleton source directory is created with your answer.
316 --list : list all installed packages (more or less "ls -d /path/to/db"...), or
317 list files from a package
318 --find-file : find the package which installed a file
320 --------------------------------------------------------------------------------
321 Trip content
322 --------------------------------------------------------------------------------
323 Inside /trip (from the trip.tar) you should find something like that :
324 /trip :
325         - trip/
326                 - bin/ : contains the trip shell script
327                 - conf/ : contains the trip configuration
328                 - doc/ : some poor documentation
329         - lfs-svn-20060416 : the LFS packages from the lfs-svn-20060416 book, as
330 an example
331                 - src/ : source package directories
332                 - bin_pkg : where the binary packages are created
333                 - src_pkg : where the source packages are created
334                 - db : the installed package database
335         - tmp : used to build packages
338 --------------------------------------------------------------------------------
339 Usage of trip during LFS chapter 6, from a host Linux system
340 --------------------------------------------------------------------------------
341 In this paragraph we explain how to use trip during the Chapter 6 of LFS. At
342 this stage the $LFS/tools is ready. Stop at "6.1 Introduction". As a starting
343 point we use LFS-SVN-20060416, but you may use another version of course.
345 Note 1 : You must have installed trip as explained before and completed the 4
346 steps.
348 Note 2 : Each package of the LFS chapter 6 has its own trip source package, but
349 there are some more trip packages not linked to a particular package. And for
350 that matter the first package is "lfs-base" and its purpose is to create the FHS
351 directory tree for example, and also some other essential files. The source
352 packages used here have in general "build.sh" and "install.sh" scripts cut and
353 pasted from the book.
355 Note 3 : during the building of the LFS system when we say "install package
356 foo-1.2.3" it means :
357         trip --build "/trip/lfs-svn-20060416/src/foo-1.2.3
358         trip --install "/trip/lfs-svn-20060416/bin_pkg/foo-1.2.3-*.tar.gz"
362 * Prepare virtual filesystem and some essential link to the shell
364   mkdir -p $LFS/{dev,proc,sys,bin,tmp}
365   mknod -m 600 $LFS/dev/console c 5 1
366   mknod -m 666 $LFS/dev/null c 1 3
367   ln -s /tools/bin/bash $LFS/bin/bash
368   ln -s bash $LFS/bin/sh
370 * install package lfs-base
372 * install package linux-libc-headers-2.6.12.0
374 * create some essential symlinks
375   ln -s /tools/bin/{cat,grep,pwd,stty} $LFS/bin
376   ln -s /tools/bin/perl $LFS/usr/bin
377   ln -s /tools/lib/libgcc_s.so{,.1} $LFS/lib
379 * install package glibc-2.3.6
381 * re-adjusting the toolchain
382   chroot "$LFS" /tools/bin/env -i HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
383 PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin /tools/bin/bash --login +h
384   mv /tools/bin/{ld,ld-old}
385   mv /tools/$(gcc -dumpmachine)/bin/{ld,ld-old}
386   mv /tools/bin/{ld-new,ld}
387   ln -s /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld
388   gcc -dumpspecs | \
389   perl -p -e 's@/tools/lib/ld-linux.so.2@/lib/ld-linux.so.2@g;' \
390       -e 's@\*startfile_prefix_spec:\n@$_/usr/lib/ @g;' > \
391           `dirname $(gcc --print-libgcc-file-name)`/specs
393 * install the following packages. Note that you will get conflicts on these
394 packages : gcc, coreutils, perl, bash, grep : this is normal because we created
395 some symlinks before. To ignore the conflict use the following command :
396         trip --no-conflict --install \
397 "/trip/lfs-svn-20060416/bin_pkg/foo-1.2.3-*.tar.gz"
399 List of packages to install in that order :
400 binutils-2.16.1
401 gcc-4.0.3
402 db-4.4.20
403 coreutils-5.94
404 iana-etc-2.00
405 m4-1.4.4
406 bison-2.1
407 ncurses-5.5
408 procps-3.2.6
409 sed-4.1.5
410 libtool-1.5.22
411 perl-5.8.8
412 readline-5.1
413 zlib-shared-1.2.3
414 zlib-static-1.2.3
415 autoconf-2.59
416 automake-1.9.6
417 bash-3.1
418 bzip2-1.0.3
419 diffutils-2.8.1
420 e2fsprogs-1.38
421 file-4.17
422 findutils-4.2.27
423 flex-2.5.33
424 gawk-3.1.5
425 gettext-0.14.5
426 grep-2.5.1a
427 groff-1.18.1.1
428 grub-0.97
429 gzip-1.3.5
430 inetutils-1.4.2
431 iproute2-2.6.16-060323
432 kbd-1.12
433 less-394
434 make-3.80
435 man-db-2.4.3
436 man-pages-2.25
437 mktemp-1.5
438 module-init-tools-3.2.2
439 patch-2.5.4
440 psmisc-22.2
441 shadow-4.0.15
442 sysklogd-1.4.1
443 sysvinit-2.86
444 tar-1.15.1
445 texinfo-4.8
446 udev-088
447 util-linux-2.12r
448 vim-6.4
449 lfs-bootscripts-20060415
450 lfs-configuration-20060416
451 linux-2.6.16.5
453 The "shadow" package requires some manual configuration :
454         chroot "$LFS" /tools/bin/env -i HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
455 PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin /tools/bin/bash --login +h
456         pwconv
457         grpconv
458         rm /etc/{passwd-,group-,shadow-,gshadow-}
459         passwd root
461 The two last packages contains some default configurations that you will
462 certainly want to change. So have a look at the content of these packages in
463 order to adapt them to your needs.
464 I suggest at this point to come back to the book at "7.5. Configuring the
465 setclock Script" for the last steps. You will in particular need to :
466 - edit /boot/grum/menu.lst
467 - edit /etc/fstab
468 - run grub
470 --------------------------------------------------------------------------------
471 Usage of trip from the LFS system
472 --------------------------------------------------------------------------------
473 Once the LFS has been completed and booted, it is time to build some more
474 packages. But before you must update the configuration of trip since the $LFS
475 mount point has changed : it is not /mnt/lfs anymore, it is /. So update your
476 /trip/trip/conf/conf files as this :
478 ---------- cut after this line -------------
479 # TRIP configuration file
480 # TRIP is a TRIvial Packager
481 # copyright 2006 Pierre Hebert <pierrot@1000wallpapers.com>
482 # http://things.1000wallpapers.com/
484 # the real root filesystem, in which resides the operating system
485 TRIP_FS_ROOT=/
487 # the filesystem on which are temporarily created the files during the install
488 phase
489 TRIP_FS_PKG=/mnt/pkg
491 # the union filesystem mergin $TRIP_FS_ROOT(ro) and $TRIP_FS_PKG(rw)
492 TRIP_FS_UNION=/mnt/union
494 # the package repository root, where packages are created
495 TRIP_PKG_ROOT=/trip/lfs-svn-20060416
497 # where to install binary packages
498 TRIP_INSTALL_DIR=/
500 # the mode tell if we use /tools or / as build environment (hosted = build from
501 /tools, normal=/)
502 TRIP_MODE=normal
504 # level of activity reporting
505 TRIP_TRACE_LEVEL=3
507 # root location of temporary files
508 TRIP_TMPDIR=/trip/tmp
509 ---------- cut before this line -------------
511 Edit your /etc/fstab and replace the /mnt/union line by something like :
512 unionfs        /mnt/union   unionfs dirs=/mnt/pkg:/=ro 0   0
513 (the "dirs" option has changed)
515 Now you can continue your LFS system with trip, if you think it worth using it.
517 --------------------------------------------------------------------------------
518 Download Trip
519 --------------------------------------------------------------------------------
520 Trip is available at :
521 http://things.1000wallpaper.com/trip/trip.tar
522 This is a 170Mb archive because it contains all source packages needed for LFS.
523 And this hint is available at 
524 http://things.1000wallpaper.com/trip
526 --------------------------------------------------------------------------------
527 Known limitations
528 --------------------------------------------------------------------------------
529  * As we merge two filesystem there is a problem if your linux installation is
530 based on several filesystem (for example / and /usr), because /usr won't be
531 visible from /mnt/union.
532 A solution (not tested yet) may be to use unionfs-fuse (see
533 http://podgorny.cz/moin/UnionFsFuse) which may be slower but is more flexible
534 that the kernel based unonfs. However unionfs-fuse seems to not support
535 currently read-only branches.
536  * trip works only on Linux, with bash. It has few prerequisites though, such as
537 tar, coreutils, grep, etc.
540 --------------------------------------------------------------------------------
541 Conclusion
542 --------------------------------------------------------------------------------
543 Trip is at alpha stage and may not go beyond beta. However I really hope this 
544 little tool and especially the idea behind the tool will be usefull or at least 
545 interesting to some LFS users, and also for non LFS users.
547 And of course, feedback will be appreciated.
550 ACKNOWLEDGEMENTS:
551   * http://www.linuxfromscratch.org/ (and BLFS too)
552   * http://www.unionfs.org/
553   * http://www.linuxfromscratch.org/hints/
555 CHANGELOG:
556 [2006-05-13]
557   * Initial hint.
558 -- 
559 http://linuxfromscratch.org/mailman/listinfo/hints
560 FAQ: http://www.linuxfromscratch.org/faq/
561 Unsubscribe: See the above information page