mkdistrep, distrepinstall — LPMtool distribution repository toolkit
mkdistrep
distdir repdir
distrepinstall
[-c configdir] [install] | [update] sysroot repdir [mountpoint...]
These tools prepare and package an entire LPMtool-based system for distribution from installable, multi-volume media. Right now this is merely a proof-of-concept; no such systems exist as of now.
mkdistrep creates a distribution repository database. distrepinstall is not a full-fledged system installer application. distrepinstall works with an external distribution installation application; the installer runs distrepinstall and communicates with it, via standard input and output.
The installer also captures the standard error output stream from distrepinstall. distrepinstall continuously sends specially-formatted messages to standard error, providing feedback on the installation process.
The first step to assembling an LPMtool-based distribution is to build
all packages.
Once that's done,
create a new directory, distdir
.
Inside distdir
create subdirectories with
numerically-increasing names, one subdirectory for each volume in the
distribution:
would be the first CD or DVD in the
distribution, distdir
/1
would
be the second one, and so on.distdir
/2
Volume names must be numeric.
Place all packages in their corresponding directories.
must contain only binary “.lp” packages.distdir
/volume
mkdistrep creates repdir
, a new
directory whose contents would only be of interest to
distrepinstall.
It is your responsibility to compute the maximum size of each volume, and
reserve sufficient space for the installation program itself (including
repdir
,
distrepinstall, and any other ancillary files required
by the installer).
The maximum size of repdir
depends only on the
total number and contents of all packages in
distdir
, and has only a mathematically non-zero
relevance on which packages get placed into which volume.
A trial run of mkdistrep can be used to determine how
much space repdir
needs; the package
volume distribution can then be set accordingly; the old
repdir
removed, then regenerated again by running
mkdistrep a second time.
It is your responsibility to verify the contents of all package files and make sure that they are not corrupted. mkdistrep does not check the integrity of the package files (but they will certainly be checked by distrepinstall). Neither mkdistrep, nor distrepinstall, checks the packages' GPG signatures, however the package files should still be signed if the distribution installer offers the ability to download the package files off an unsecure network. The installer is responsible for checking each package file's signature before giving the package file to distrepinstall to install.
distrepinstall is not a complete operating system installer. It only handles the low-level work of uncompressing and installing package files. It's intended to be invoked by an interactive installation program. The installation program choses the packages to install, then creates and format all partitions.
The system root partition is typically mounted somewhere
within the installation media's filesystem. As an example, the
Anaconda
installer mounts the system root directory as
/mnt/sysimage
.
Other partitions are mounted inside it, such as
/mnt/sysimage/usr
and
/mnt/sysimage/home
.
Once the partitions are mounted, the installer runs distrepinstall with the following arguments:
configdir
This is an optional argument for
distrepinstall's install mode.
distrepinstall is a customized subset of the
lpm command, which reads a configuration file
setup.lp
from a predefined location
(usually /usr/local/share/lpmtool
or
/usr/share/lpmtool
).
setup.lp
must be copied to the system root partition.
distrepinstall takes care of this, and expects to find
setup.lp
in its default location.
If the default configuration directory is
/usr/share/lpmtool
and
the system root directory is mounted as
/mnt/sysimage
,
distrepinstall copies
/usr/share/lpmtool/setup.lp
to
/mnt/sysimage/usr/share/lpmtool/setup.lp
.
The -c
option overrides the directory
distrepinstall copies the file from
(the destination directory obviously does not change).
distrepinstall copies setup.lp
only
in install mode, presumably because the system root directory is empty, and
waiting for a new install.
In update mode
the system root directory is expected to already have a working
LPMtool-based system, and there's no need to copy the configuration file.
A drastically hacked setup.lp
of an existing system
may prevent distrepinstall from working properly.
install
or
update
“install” runs
distrepinstall
in install mode.
The system root directory should be freshly formatted, and empty.
distrepinstall
creates a new system repository, then reads the list of packages to
install from standard input.
Each line contains one package name, formatted as
“name
(arch
)-version
-release
”.
An empty line follows the last package's name.
“update” runs
distrepinstall
in update mode.
The system root directory is expected to already have a working, but older,
LPMtool-based system.
distrepinstall
reads its system package repository and automatically selects all available
packages for update.
distrepinstall
does not read anything from standard input in update
mode,
it already has all the information it needs to select packages for
update.
“sysroot
” is the mount point of the
system root partition, such as
“/mnt/sysimage
”.
distpreinstall forks internally.
One of the processes
chroot(2)s
itself to sysroot
, where it installs
or updates the packages.
The other process continues to run in the installer's original root
directory, and acts as an intermediary between the installer, and
the process running in the sysroot
environment.
This is the location of the distribution repository that was created by
mkdistrep.
The distribution repository must be accessible from inside
sysroot
, and this pathname must be relative to
sysroot
as well.
There are two ways to do that:
Mount the installation volume that contains the distribution repository inside the system root partition, and specify the pathname to the repository directory on the installation volume.
Create a mountable filesystem image that contains the distribution repository (mkisofs will do nicely) and mount the filesystem image using the loopback device, inside the system repository.
The distribution repository is only needed long enough for mkdistrep to figure out what packages get installed or updated. After mkdistrep figures this out and begins installing packages, the distribution repository directory is no longer needed.
repdir
can be unmounted as soon as distrepinstall begins installing
the first package.
mountpoint
list
The remaining arguments to
distrepinstall
is a list of any other partitions the installer mounted inside the system
root partition.
No arguments necessary if the system to be installed or updated resides on
a single root partition.
Otherwise, for example, if the system root partition is mounted as
/mnt/sysimage
, and additional filesystem are mounted as
/mnt/sysimage/usr
and
/mnt/sysimage/home
, then
distrepinstall
needs to have “/usr” and “/home” listed as the
additional mounted partitions.
The operating system installer communicates with
distrepinstall via its standard input, output, and error.
The installer must set up the appropriate pipes to
distrepinstall's
stdin
,
stdout
, and
stderr
.
The installer must simultaneously read the output of
distrepinstall's
stdout
and
stderr
, at the same time.
When distrepinstall wants to install a package,
distrepinstall will write
“volume
/filename
”,
followed by a newline character, on its standard output.
The installer must change distribution volumes, if necessary, then
write the full pathname of the requested package file
to distrepinstall's
stdin
channel.
The package file need not be made available within the
installed system's root directory.
The package file can be accessible from anywhere in the installer's
filesystem.
The distrepinstall process running inside the
chroot
jail uses dark magic to open the package file
outside of its jail environment.
The package file must remain available either until
distrepinstall asks for the next package file, or until
it's done, and closes its stdin
channel.
Before running distrepinstall,
its executable binary should be copied somewhere inside
sysroot
, and that copy should be executed with
its current directory also set to sysroot
.
This should eliminate all references to the original installation media,
allowing it to be unmounted.
distrepinstall's standard error will have a variety of messages that provide feedback of its progress. The following messages can appear at any time, and the installer must always be prepared to read them, in order to avoid deadlocks:
*ERROR
message
An error has occured.
Installation may or may not proceed.
The error message
must be displayed in a
conspicuous,
loud manner.
*FAILURE
message
An error message that spans multiple lines.
Each line in the error message is given in each occurence of
*FAILURE
;
several *FAILURE
messages appear consecutively.
The last line of the error message is followed by *ENDFAILURE
.
*ENDFAILURE
This message marks the end of a multiline error message.
*INFO
message
An informational message.
The message
should be logged, somewhere,
and at the conclusion of the installation the log file should be perused,
in case something interesting happened.
*DEBUG
message
A debug message.
The message
should be logged, somewhere.
It should not be necessary to review the contents of the debug log file,
unless there's plenty of idle time and there's nothing better to occupy
one's time.
*FEEDBACK
x
y
message
distrepinstall is in a middle of doing something that
could take a while.
distrepinstall's best guess is that it's completed step
#x
out of #y
steps total.
This should be used to display a progress bar indication, with
message
as its caption.
At the conclusion of the process both
#x
out of #y
will be
zero, and should be interpreted as a 100% completion.
A lot of *FEEDBACK
messages can appear very quickly and
it may not be feasible to go through the rigamarole of computing the
progress bar's image and updating it, every time.
The installer should pace itself and only update its display at reasonable
intervals.
The 100% completion indication should always be shown.
*UNRESOLVED
dependency
Some unresolved dependencies still remain after all packages were selected for installation or update. This usually happens if additional packages, besides the base distribution, were installed and their required resources are going to be removed.
distrepinstall issues one *UNRESOLVED
message for each unresolved dependency, and all unresolved dependencies will
be reported at the same time.
distrepinstall will continue and proceed with the
installation despite the unresolved dependency.
It's up to the installation application to choose whether to abort and
terminate the installation process.
*CONFLICT
dependency
The installation/update will introduce a dependency conflict. This usually happens if additional packages, besides the base distribution, were installed and their resources conflict with the resources from the packages about to be installed or updated.
distrepinstall issues one *CONFLICT
message for each conflicting dependency, and all conflicting dependencies will
be reported at the same time.
distrepinstall will continue and proceed with the
installation despite the unresolved dependency.
It's up to the installation application to choose whether to abort and
terminate the installation process.
*CHECKED
This message marks the end of *UNRESOLVED
and
*CONFLICT
messages.
The *CHECKED
message is issued
only if at least one *UNRESOLVED
and
*CONFLICT
message was issued.
*PACKAGES
a
b
c
d
This is overall package installation progress indication.
distrepinstall is installing
#d
packages whose estimated size is
#c
bytes.
Out of that
#b
packages, with
#a
bytes have been already installed.
Byte counts are 64 bit numbers.
All other messages should be treated as *DEBUG
messages.
They're likely to be the unintended output of individual packages'
installation scripts.
It is impossible to accurately compute, down to the last byte, how much disk space is required to install a set of packages. distrepinstall tries to make a good, educated guess. Hopefully, it'll err on the side of safety.
distrepinstall
will read the entire repdir
into memory.
The available system RAM places an upper limit on the
size of the entire distribution.
We'll cross that bridge when we come to it.
The order the packages get installed is not guaranteed. distrepinstall will try to process packages from consecutive volumes, in an orderly fashion, to minimize the volume changes. This will work only if the packages are properly partitioned in volumes, according to their dependencies. No package should depend on another package in a later volume, otherwise distrepinstall will prompt for that package, then prompt for the remaining packages in the original volume.
For new installs, the installer should probably install a skeleton
/etc/passwd
file before running
distrepinstall in install mode.
distrepinstall needs to lookup the numeric userid and
groupid values in order to correctly set the ownership of each file it
installs (it'll default to root
, after voicing a complaint,
if it can't figure it out).
The alternative is to explicitly have every package declare a dependency
on a package whose sole contents are the
stock /etc/passwd
file (there'll still be one complaint logged, because
distrepinstall won't know who should own
/etc/passwd
until it's actually installed, but
it'll default to root
and that's going to be good
enough).