From 948660490fd3768e98ff7fc98a4428406f23c1c6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mat=C3=ADas=20Fonzo?= Date: Thu, 25 Apr 2019 16:39:33 -0300 Subject: [PATCH] website: start adding content to the manual --- website/en/manual.html | 10 +- website/en/manual.t2t | 6 +- website/manual/en/about.html | 14 + website/manual/en/about.t2t | 5 + website/manual/en/configuration.html | 14 + website/manual/en/configuration.t2t | 5 + website/manual/en/genhtmldocs | 21 + website/manual/en/graft.html | 3468 +++++++++++++++++ website/manual/en/html_node/about.html | 36 + website/manual/en/html_node/configuration.html | 39 + website/manual/en/html_node/index.html | 65 + website/manual/en/html_node/installation.html | 39 + website/manual/en/html_node/pkgmanagement.html | 3494 +++++++++++++++++ website/manual/en/installation.html | 14 + website/manual/en/installation.t2t | 5 + website/manual/en/pkgmanagement.html | 4889 ++++++++++++++++++++++++ website/manual/en/pkgmanagement.t2t | 8 + website/manual/en/qi.html | 1406 +++++++ website/manual/index.html | 3 + 19 files changed, 13533 insertions(+), 8 deletions(-) create mode 100644 website/manual/en/about.html create mode 100644 website/manual/en/about.t2t create mode 100644 website/manual/en/configuration.html create mode 100644 website/manual/en/configuration.t2t create mode 100755 website/manual/en/genhtmldocs create mode 100644 website/manual/en/graft.html create mode 100644 website/manual/en/html_node/about.html create mode 100644 website/manual/en/html_node/configuration.html create mode 100644 website/manual/en/html_node/index.html create mode 100644 website/manual/en/html_node/installation.html create mode 100644 website/manual/en/html_node/pkgmanagement.html create mode 100644 website/manual/en/installation.html create mode 100644 website/manual/en/installation.t2t create mode 100644 website/manual/en/pkgmanagement.html create mode 100644 website/manual/en/pkgmanagement.t2t create mode 100644 website/manual/en/qi.html create mode 100644 website/manual/index.html diff --git a/website/en/manual.html b/website/en/manual.html index 148d61ec..bc8a31b7 100644 --- a/website/en/manual.html +++ b/website/en/manual.html @@ -20,12 +20,12 @@ < Back to home

-The manual for dragora is available in the following formats: +Documentation for dragora is available in the following formats:

@@ -37,7 +37,7 @@ The manual for dragora is available in the following formats:


-23 April 2019, 19:02 +25 April 2019, 19:29 See sources ~ Validate HTML | GNU Free Documentation License @@ -46,5 +46,5 @@ The manual for dragora is available in the following formats: - + diff --git a/website/en/manual.t2t b/website/en/manual.t2t index 8f9ff92f..c603bf0c 100644 --- a/website/en/manual.t2t +++ b/website/en/manual.t2t @@ -5,10 +5,10 @@ Documentation for Dragora [< Back to home index.html] -The manual for dragora is available in the following formats: +Documentation for dragora is available in the following formats: -- HTML (xK) - entirely on one web page. -- PDF file. +- [HTML ../manual/en/html_node/index.html] - with one web page per node. +- PDF file (coming soon). [^ Go up manual.html#]''
'' diff --git a/website/manual/en/about.html b/website/manual/en/about.html new file mode 100644 index 00000000..e54fa59f --- /dev/null +++ b/website/manual/en/about.html @@ -0,0 +1,14 @@ + + + + + +

+
+ + +

Part I - Introducing Dragora

+ + + + diff --git a/website/manual/en/about.t2t b/website/manual/en/about.t2t new file mode 100644 index 00000000..cfdd7ca1 --- /dev/null +++ b/website/manual/en/about.t2t @@ -0,0 +1,5 @@ + + + += Part I - Introducing Dragora = + diff --git a/website/manual/en/configuration.html b/website/manual/en/configuration.html new file mode 100644 index 00000000..3c50bfef --- /dev/null +++ b/website/manual/en/configuration.html @@ -0,0 +1,14 @@ + + + + + +
+
+ + +

Part III - Configuration

+ + + + diff --git a/website/manual/en/configuration.t2t b/website/manual/en/configuration.t2t new file mode 100644 index 00000000..593b4a82 --- /dev/null +++ b/website/manual/en/configuration.t2t @@ -0,0 +1,5 @@ + + + += Part III - Configuration = + diff --git a/website/manual/en/genhtmldocs b/website/manual/en/genhtmldocs new file mode 100755 index 00000000..56979b81 --- /dev/null +++ b/website/manual/en/genhtmldocs @@ -0,0 +1,21 @@ +#! /bin/sh + +set -e +set -x + +rm -rf html_node +mkdir html_node + +htmldoc -t html -d html_node \ + --no-title \ + --toclevels 2 \ + --toctitle "Dragora Documentation" \ + ./about.html ./installation.html ./configuration.html \ + ./pkgmanagement.html + +# Adjust main title + +sed -i \ + 's#Qi user guide#Dragora Documentation#' \ + ./html_node/index.html + diff --git a/website/manual/en/graft.html b/website/manual/en/graft.html new file mode 100644 index 00000000..281bbb4a --- /dev/null +++ b/website/manual/en/graft.html @@ -0,0 +1,3468 @@ + + + +Graft + + + + +
+

Graft - a package management utility

+
+ +

Prepared by Peter Samuel +<peter.r.samuel@gmail.com>

+ +

$Revision: 2.16 $

+

$Date: 2018/04/16 14:54:07 $

+ +
+

graft: To insert (a graft) in a branch or stem + of another tree; to propagate by insertion in another stock; also, to + insert a graft upon. To implant a portion of (living flesh or skin) in + a lesion so as to form an organic union. To join (one thing) to another + as if by grafting, so as to bring about a close union.

+
+ +
+ +

Contents

+ + + +
+ +

Introduction

+ +

Graft provides a mechanism for managing multiple packages +under a single directory hierarchy. It was inspired by both Depot +(Carnegie Mellon University) and Stow (Bob Glickstein).

+ +

For the purposes of this discussion a package is defined as +a suite of programs and files that make up an individual product. For +example, the package known as gcc consists of the compiler +and preprocessor programs, include files, manual pages and any other +associated file or program. The concept of a package should not be +confused with some vendor's definitions that are - by this definition - +actually collections of packages.

+ +

Special thanks to Gordon Rowell, Charles Butcher, Charlie Brady, +Robert Maldon and Matias A. Fonzo for design suggestions and contributions. +

+ +
+ +

Rationale

+ +

In any reasonably large environment, many software packages will be +installed. The installation location for these packages usually follows +one of three rationales - each with its own advantages and drawbacks:

+ +
    + +
  1. Each package is isolated from all other packages by + installing it into a self contained directory tree. All binaries, + manual pages, library and configuration files are stored under + a single directory tree. This directory tree contains NO other + files which are not the exclusive domain of the package in + question.

    + +

    This method makes package demarcation obvious. As each + package is self contained, identification of any file within a + package is immediately apparent.

    + +

    Multiple versions of packages can be installed fairly easily + to accommodate acceptance testing of new versions and/or legacy + systems.

    + +

    However, the use of individual package directories can + lead to VERY long $PATH and $MANPATH environment + variables. Some shells may not be able to handle such long + variables. Whenever a new package is added, each user MUST + update their $PATH and $MANPATH to make the package + available.

    + +
  2. Packages are installed under a common directory tree. + Binaries for all packages are grouped in a single directory, + manual pages for all packages in another directory and so on. +

    + +

    This method eliminates the need for continually updating long + $PATH variables for each user. As soon as a package is + placed into the common 'bin' directory it is immediately + available to all users (after a shell rehash if necessary).

    + +

    However, when a package is to be updated it is often very + difficult to isolate all the files related to a particular + package if they are intermingled with unrelated files.

    + +
  3. A combination of methods (1) and (2).

    + +
+ +

In an effort to maximise the advantages and minimise the +disadvantages, Depot, Stow and Graft adopt a similar +philosophy:

+ +
+

Packages are installed in self contained directory trees and + symbolic links from a common area are made to the package files.

+
+ +

This approach allows multiple versions of the same package to co-exist +on the one system. One version is the commonly available version and +symbolic links will be made to this version. New versions can be tested +and once acceptable can replace the current commonly available version. +Older versions can still be used for legacy systems by using the +'real' path name to the package instead of the 'common' +path name.

+ +

The size and complexity of environment variables such as $PATH +and $MANPATH is minimised because only the common area is +required. Any special cases can also be accommodated but these will +usually be in the minority when compared with the number of commonly +available packages.

+ +
+ +

Research

+ +

Note: Development of Graft began in late 1996. The +comments regarding the packages listed below reflect their functionality +and behaviour at that time and may not necessarily reflect their current +functionality and behaviour.

+ +

As stated earlier, Graft was inspired by Depot and +Stow. Both these systems were examined and finally rejected for +the following reasons:

+ +
+ +
Depot + ftp://ftp.andrew.cmu.edu/pub/depot/depot.tar.gz + +

Depot is very flexible yet cumbersome.

+ +

It requires a database file to be created which + provides a snapshot of the current state of both the package + repository and the Depot target. It is possible to + inadvertently destroy the package repository if the database + is damaged.

+ +

Depot assumes "ownership" of the + target area, making it almost impossible to accommodate + packages that are not under the control of Depot. + ("Ownership" in this case means that Depot + assumes ALL files in the target area will be under the + control of Depot. It does not imply that Depot + modifies Unix file permissions).

+ +

Because of Depot's assumed ownership it is + difficult for other packages not under the control of + Depot to be placed in the same target area.

+ +

Depot attempts to impose a fixed package repository + relative to the package target. It assumes that all + packages will be stored under + 'dir/depot/package' and the target + will be 'dir'. This can be overridden on + the command line but the internals of Depot make + this mechanism cumbersome.

+ +

Depot is written in C and there are many source + files in its distribution. Local modifications would be + difficult to quickly implement and test.

+ +
Stow + https://www.gnu.org/software/stow/ + +

Stow is a stateless system. It requires no + database or configuration information.

+ +

Like Depot, it assumes that the package repository + will be stored under 'dir/stow/package' + and the target will be 'dir'. This can be + overridden on the command line and works well during the + install phase.

+ +

Stow assumes "ownership" + of the target area, making it difficult to accommodate + packages that are not under the control of Stow. + ("Ownership" in this case means that Stow + assumes ALL files in the target area will be under the + control of Stow. It does not imply that Stow + modifies Unix file permissions).

+ +

Because of Stow's assumed ownership + it is difficult for other packages not under the control + of Stow to be placed in the same target area. When + deleting packages, Stow examines everything in the + target directory - whether it is associated with the package + it is trying to delete or not. This can be time consuming and + potentially dangerous as empty directories are also removed + - even empty directories that do not belong to the package + being removed.

+ +

Stow has a clever feature of folding and + unfolding directories. It attempts to optimise the + number of symbolic links by making links to directories if + the directory is only associated with a single package. If + at a later date Stow discovers another package that + needs that directory it will unfold that directory + into a collection of symbolic links to files rather than + a single symbolic link to the directory. Stow will + fold the directory when removing packages if the + remainder of the directory is only concerned with a single + package. While clever, this feature is probably a waste of + time and effort. It means that the entire package target + must be scanned to determine package ownership of links and + as packages will usually be replaced by newer versions a + directory fold will probably be short lived.

+ +

Stow will sometimes miss potential conflicts when + run in show only mode. The conflicts may occur when a + directory is unfolded and will not show up in show only + mode.

+ +

Stow's author suggests that packages be compiled + such that they refer to files in the target location rather + than the actual package installation directory. This approach + precludes the use of multiple versions of packages with + different configuration and/or library files.

+ +

Stow is written in Perl and is only a + few hundred lines of code so local modifications can be + accommodated. However there are very few comments in the + code which makes the process of modification difficult.

+ +
+ +

Since the release of Graft 1.6, the existence of yet another +packaging program has been brought to the author's attention.

+ +
+ +
Encap + http://www.ks.uiuc.edu/Development/Computers/docs/sysadmin/Build/encap.html + +

Encap grew out of work begun at the University + of Illinois Champaign-Urbana. It has the same underlying + philosophy as Depot, Stow and Graft - + encapsulate packages into self contained directories and use + symbolic links to make them visible in a common location.

+ +

Encap uses a combination of a csh wrapper + and a Perl program to accomplish its work. Like both + Depot and Stow, Encap assumes that all + compiled packages will live under a single directory hierarchy + - by default 'dir/encap/package'. It + then attempts to create a symbolic link tree for ALL the + packages under this area. There doesn't appear to be any + easy way to support the quick addition or removal of a single + package.

+ +

A new release of Encap incorporating many new + features was expected to be available in early 1997, however + no release greater than version 1.2 has been forthcoming.

+ +

One good feature of Encap is the ability to exclude + specific files from the package tree. This concept has been + incorporated into Graft 1.7 and above.

+ +
+ +

Since the release of Graft 2.3, the existence of +several another packaging programs have been brought to the author's +attention. Rather than outline their features and whether or not the +author feels they are superior (or inferior) to Graft, a reference +to each package and a brief description is given and further research +is left as an exercise for the reader:

+ +
+ +
stowES + +
+ +
+https://os.inf.tu-dresden.de/~adam/stowES/
+
+ +

"stowES (stow Enhancement Script) is + a Perl script which tries to ease the use of the "stow" + packaging program and software which can be compiled and + installed with autoconf. It automates the compilation and + installation of software packages and provides some useful + functions to maintain your stow packages (e.g., list packages, + check packages for integrity, etc.)."

+ +
opt_depot + +
+ +
+https://github.com/jonabbey/opt_depot
+
+ +

"opt_depot is a suite of Perl scripts which makes + it easy to manage installed software across a wide range + of client systems. opt_depot makes it possible to keep all + files associated with a program together in one directory, + so installation and de-installation is simple. opt_depot is + easy to manage, and provides a scheme for installing software + in a truly portable fashion; packages may be installed locally + on client systems, or kept in a central package archive for + NFS access. "

+ +

This site also has links to several other package + management utilities, including Graft.

+ +
relink + +
+ +
+http://sourceforge.net/projects/relink/
+
+ +

"relink is a package management tool for + organization and management of software packages. It should + run on any UNIX platform that runs PERL. Similar tools + include: rpm(REDHAT/Mandrake), pkgadd(Slackware/SUN), + stow(GNU) and depot(CMU)"

+ + +
univSrcPkg + +
+ +
+http://freecode.com/articles/the-universal-source-package
+
+ +

Bud Bruegger has written + a brief paper outlining his thoughts on a "Universal Source + Package" solution.

+ +

This site also has links to other package management + programs and similar items of interest.

+ +
+ +
+ +

Design

+ +

This brings us to Graft. Graft has been designed to +use the best features of Depot, Stow and Encap +while maintaining as simple a mechanism as possible. The principles of +Graft are:

+ + + +

Control file precedence & conflict resolution

+ +

As stated above, the various Graft control files have the +following precedence, from highest to lowest:

+ +
+    .nograft > .graft-exclude > .graft-include > .graft-config
+
+ +

The following table summarises the activities of Graft when +various control files are present:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Install +
+ Target + + .nograft + + .graft-exclude + + .graft-include + + .graft-config +
+ does not exist + + IGNORE + + IGNORE + + SYMLINK + + COPY +
+ symlink to source + + IGNORE + + IGNORE + + NOP + + DELETE & COPY +
+ symlink to other + + IGNORE + + IGNORE + + CONFLICT + + N/A +
+ symlink to other (crc match) + + N/A + + N/A + + N/A + + NOP +
+ symlink to other (crc diff) + + N/A + + N/A + + N/A + + COPY.new +
+ file + + IGNORE + + IGNORE + + CONFLICT + + N/A +
+ file (crc match) + + N/A + + N/A + + N/A + + NOP +
+ file (crc diff) + + N/A + + N/A + + N/A + + COPY.new +
+ not a file + + IGNORE + + IGNORE + + CONFLICT + + CONFLICT +
+ Delete +
+ Target + + .nograft + + .graft-exclude + + .graft-include + + .graft-config +
+ does not exist + + NOP + + NOP + + NOP + + NOP +
+ symlink to source + + DELETE + + DELETE + + DELETE + + DELETE & DELETE.new +
+ symlink to other + + CONFLICT + + CONFLICT + + CONFLICT + + N/A +
+ symlink to other (crc match) + + N/A + + N/A + + N/A + + DELETE.new +
+ symlink to other (crc diff) + + N/A + + N/A + + N/A + + NOP +
+ file + + NOTE + + NOTE + + CONFLICT + + N/A +
+ file (crc match) + + N/A + + N/A + + N/A + + DELETE.new +
+ file (crc diff) + + N/A + + N/A + + N/A + + NOP +
+ not a file + + CONFLICT + + CONFLICT + + CONFLICT + + CONFLICT +
+ Prune +
+ Target + + .nograft + + .graft-exclude + + .graft-include + + .graft-config +
+ does not exist + + NOP + + NOP + + NOP + + N/A +
+ symlink to source + + NOP + + NOP + + NOP + + N/A +
+ symlink to other + + PRUNE + + PRUNE + + PRUNE + + N/A +
+ file + + PRUNE + + PRUNE + + PRUNE + + N/A +
+ not a file + + PRUNE + + PRUNE + + PRUNE + + N/A +
+
+ +
+ +

History

+ +

Development on Graft began in October 1996. The initial design +used a configuration file to map the installed location of each package to +its target directory (that is the directory in which the symbolic links +would be created). Work proceeded at a regular pace and by November 1997 +Graft version 2.1 was released. In this, and all +subsequent versions, the configuration file had been removed in favour of +using default source and target directories.

+ +

No further work was performed until September 2000 when the concept of +bypassing or including files and directories using .nograft or +.graft-include files was introduced in Graft version +2.3.

+ +

Again nothing changed until February 2002 when Rod Whitby identified a +bug in the handling of .graft-include files. Several other users +(Peter Bray, Robert Maldon and others) also reported some deprecation +warnings when using Graft with Perl version +5.6.0. Graft version 2.4 was the end of +Graft development for over a decade.

+ +

In May 2015 Matias A. Fonzo contacted the author wishing to use +Graft in the +Dragora GNU/Linux +distribution. Matias' usage of Graft lead to Graft +version 2.5 in June 2015 whereby the -P command line +option was silently ignored if the effective user was not root.

+ +

Since the release of Graft version 2.4 the author's +Perl code had improved somewhat so Graft version +2.6 released in July 2015 represented a major clean up of coding +style and internals. No new behaviours or features were added to the +2.6 release.

+ +

Matias made some more suggestions and improvements up to and including +Graft version 2.16 in April 2018. These changes added +the .graft-config control file, the -r /rootdir option for +specifying a new root directory, the -L option for displaying +default locations as well as introducing some tighter controls on the +messages and exit status of Graft under various conditions.

+ +
+ +

Installation

+ +

Before installing Graft you'll need Perl +5.x. Graft version 2.x requires features only +available with Perl 5.x and will not run with +Perl 4.x.

+ +

Your operating system and its file system(s) should also support +symbolic links. If you can't make symbolic links then you can't use +Graft! Graft will exit gracefully if your version of +Perl does not support symbolic links. It will also exit gracefully +if you attempt to graft a package into a file system that does not +support symbolic links - from a Linux ext4 file system into an +vfat file system for example.

+ +

Graft has been written to ensure it uses Perl modules +that are considered part of the core Perl distribution. However it +may be possible that you're using a home grown installation of +Perl or some distribution that doesn't have the same Perl +modules as the author's development environment.

+ +

If this is the case you'll see compile failures for the following modules +if they are unavailable:

+ +
+   File::Basename
+   Getopt::Long
+
+ +

You will not be able to install Graft until these modules are +available.

+ +

You may also see run-time failures when using Graft with +.graft-config files if the following modules are unavailable:

+ +
+   Compress::Raw::Zlib    (used in install and delete modes)
+   File::Copy             (only used in install mode)
+
+ +

If you don't have these modules and you do not intend to use +.graft-config files then you can continue to use Graft +without issue.

+ +

Follow these instructions to install Graft:

+ +
    + +
  1. Unpack the gzipped Graft distribution:

    + +
    +    gunzip -c graft-2.16.tar.gz | tar xvf -
    +
    + +
  2. change directories to the Graft distribution + directory:

    + +
    +    cd graft-2.16
    +
    + +
  3. Create an writable version of the Makefile by + running the command

    + +
    +    make -f Makefile.dist
    +
    + +

    You'll see output similar to

    + +
    +    cp Makefile.dist Makefile
    +    chmod 644 Makefile
    +
    +    ######################################################
    +    #                                                    #
    +    #       You'll now need to modify the Makefile       #
    +    #      variables to suit your local conditions.      #
    +    #                                                    #
    +    ######################################################
    +
    +    make: *** [Makefile] Error 1
    +
    + +

    You can ignore the error message. That is just there to + prevent the creation of the graft executable before you've + made your site specific configurations to the Makefile. +

    + +
  4. Edit the Makefile. The following variables should be + modified to suit your local requirements:

    + +
    + +
    +
    +PACKAGEDIR     = /usr/local/pkgs
    +TARGETDIR      = /usr/local
    +
    + +

    These two variables control your default + package installation and target + directories. Most sites will probably choose to + install packages under a common installation + directory and then graft them into a common + target directory.

    + +

    If no specific target directory is + given on the command line, Graft will use + the default value specified by TARGETDIR. If + a target directory is given on the command + line but is not fully qualified, the value specified + by TARGETDIR will be prepended to the command + line argument.

    + +

    Package names provided to Graft that are + not fully qualified will have the value specified + by PACKAGEDIR prepended to the command line + arguments.

    +
    +
    +TOP            = $(PACKAGEDIR)/graft-$(VERSION)
    +BIN            = $(TOP)/bin
    +MAN            = $(TOP)/man
    +DOC            = $(TOP)/doc
    +
    + +

    There should be no need to modify these + values unless you wish to install Graft into + a directory that is different from your default + package installation directory. If you do modify + TOP you should not change the values of + BIN, MAN and DOC. If you feel + you must change these values then perhaps you've + misunderstood the concept behind Graft so a + re-read of this document may be in order.

    + +
    +
    +PERL           = /usr/bin/perl
    +
    + +

    This variable refers to the location + of the Perl 5.x that will be used by + the Graft executable. If you plan on + grafting Perl then this value should + be the grafted location of Perl + rather than the installation location of Perl. + If you are using an operating system that comes with + Perl 5.x - such as RedHat or Ubuntu + Linux - then you don't need to worry about + grafting Perl so the value of + PERL should reflect its installed + location.

    + +

    Most Unix, Linux and other Unix like operating + systems ship with Perl these days so + modifying this value is probably unnecessary.

    + +
    +
    +BUILDPERL      = $(PERL)
    +
    + +

    Perl is required during the + make. You'll only need to change this if + the current installed location of Perl is + different to the future grafted location of + Perl.

    + +
    +
    +LOGFILE                = /var/log/graft
    +
    + +

    Graft logs all of its actions to a log + file. Modify the value of LOGFILE to suit + your local needs. An alternative name can be + specified on the command line.

    + +

    If you want logging disabled by default, set the + value of LOGFILE to /dev/null.

    + +
    +
    +GRAFT-IGNORE   = .nograft
    +GRAFT-EXCLUDE  = .graft-exclude
    +GRAFT-INCLUDE  = .graft-include
    +GRAFT-CONFIG   = .graft-config
    +
    + +

    These variables hold the names of the + special Graft files that control whether or + not subdirectories or files are grafted. If + you change these values, try to choose obvious names. + If you want the files to appear in a simple directory + listing, do not use file names that begin with a + dot "." character.

    + +
    +
    +GRAFT-NEVER    =
    +
    + +

    This variable holds the names of the + files and/or directories that should never be + grafted. Typically these may be source code + repositories as used by systems such as + CVS, or perhaps lockfiles. The default + value is empty but if you wish to specify values, + simply add them to the variable using only + whitespace as a separator. For example:

    + +
    +GRAFT-NEVER     = CVS RCS SCCS .lock
    +
    + +
    +
    +NEVERGRAFT     = 0
    +
    + +

    If this variable is set to 1, + the files and/or directories specified by + GRAFT-NEVER will be automatically excluded + from the grafted directory.

    + +

    If this variable is set to 0, the files + and/or directories specified by GRAFT-NEVER + will be not be excluded from the grafted + directory.

    + +

    The sense of this value is reversed by use of + the -C command line option. + +

    The automatic exclusion is bypassed completely + if the grafted directory contains either + a .nograft or .graft-include + file.

    + +
    +
    +PRUNED-SUFFIX  = .pruned
    +
    + +

    This variable sets the suffix name of + pruned files. Pruned files will be + renamed filename.pruned.

    + +
    +
    +CONFIG-SUFFIX  = .new
    +
    + +

    This variable sets the suffix name of configuration + files that will be copied to the target directory when + the target object is in conflict with the package + object. The files will be copied as + filename.new.

    + +
    +
    +SUPERUSER      = 1
    +
    + +

    If this variable is set to 1 only + the superuser can install, delete + or prune packages. This can be overridden + by the use of the -u command line + option. If this variable is set to 0, + superuser privileges are not required and the + -u override command line option is + disabled.

    + +

    If you are installing a private copy of + Graft to manage packages in your home + directory you should set SUPERUSER to + 0.

    + +

    If you're using Graft to manage a global + set of packages you should set SUPERUSER + to 1.

    + +
    +
    +PRESERVEPERMS  = 0
    +
    + +

    When grafting packages, Graft + will create new directories as required. By setting + PRESERVEPERMS to 1, + the original user id, group id and file modes will be + carried over to the new directory. This variable is + used only if SUPERUSER is set to + 1. The sense of this variable can be + reversed using the -P command line + option.

    + +
    +
    +DELETEOBJECTS  = 0
    +
    + +

    When deleting grafted packages, + Graft may leave empty directories. Setting + DELETEOBJECTS to 1 + will allow Graft to delete these directories. + If DELETEOBJECTS is 0 + then Graft will display an appropriate message + reminding the user that a directory has been emptied. + The sense of this variable can be reversed using the + -D command line option.

    + +

    It's probably not good practise to set this value + to 1 as some directories may be used + as place holders by a number of different packages. If + the value is set to 0 deletion of + directories can be forced via the -D + command line option.

    + +

    When pruning packages, graft can either + remove conflicting files or rename them. If + DELETEOBJECTS is set to + 1 the default prune action will be to + delete conflicting objects. If + DELETEOBJECTS is set to + 0 the default prune action will be to + rename conflicting objects. The sense of this variable + can be reversed using the -D command + line option.

    + +
    + +

    Save your changes and exit from the editor.

    + +
  5. Remove any existing executables by running:

    + +
    +    make clean
    +
    + +

    You should see output similar to:

    + +
    +    rm -f graft
    +
    + +
  6. Create the Graft executable by running:

    + +
    +    make
    +
    + +

    You should see output similar to:

    + +
    +    /usr/bin/perl -wc graft.pl
    +    graft.pl syntax OK
    +    sed                                         \
    +        -e 's#xCONFIG-SUFFIXx#.new#g'           \
    +        -e 's#xDELETEOBJECTSx#0#g'              \
    +        -e 's#xGRAFT-CONFIGx#.graft-config#g'   \
    +        -e 's#xGRAFT-EXCLUDEx#.graft-exclude#g' \
    +        -e 's#xGRAFT-IGNOREx#.nograft#g'        \
    +        -e 's#xGRAFT-INCLUDEx#.graft-include#g' \
    +        -e 's#xGRAFT-NEVERx##g'                 \
    +        -e 's#xLOGFILEx#/var/log/graft#g'       \
    +        -e 's#xNEVERGRAFTx#0#g'                 \
    +        -e 's#xPACKAGEDIRx#/usr/local/pkgs#g'   \
    +        -e 's#xPERLx#/usr/bin/perl#g'           \
    +        -e 's#xPRESERVEPERMSx#0#g'              \
    +        -e 's#xPRUNED-SUFFIXx#.pruned#g'        \
    +        -e 's#xSUPERUSERx#1#g'                  \
    +        -e 's#xTARGETDIRx#/usr/local#g'         \
    +        < graft.pl > graft
    +    chmod +x graft
    +    /usr/bin/perl -wc graft
    +    graft syntax OK
    +    if [ -n "" ];                                       \
    +    then                                                \
    +        AUTOIGNORE=1;                                   \
    +    else                                                \
    +        AUTOIGNORE=0;                                   \
    +    fi;                                                 \
    +    sed                                                 \
    +        -e "s#xAUTOIGNOREx#$AUTOIGNORE#g"               \
    +        -e 's#xCONFIG-SUFFIXx#.new#g'                   \
    +        -e 's#xDELETEOBJECTSx#0#g'                      \
    +        -e 's#xDOCx#/usr/local/pkgs/graft-2.16/doc#g'   \
    +        -e 's#xGRAFT-CONFIGx#.graft-config#g'           \
    +        -e 's#xGRAFT-EXCLUDEx#.graft-exclude#g'         \
    +        -e 's#xGRAFT-IGNOREx#.nograft#g'                \
    +        -e 's#xGRAFT-INCLUDEx#.graft-include#g'         \
    +        -e 's#xGRAFT-NEVERx##g'                         \
    +        -e 's#xLOGFILEx#/var/log/graft#g'               \
    +        -e 's#xNEVERGRAFTx#0#g'                         \
    +        -e 's#xPACKAGEDIRx#/usr/local/pkgs#g'           \
    +        -e 's#xPERLx#/usr/bin/perl#g'                   \
    +        -e 's#xPRESERVEPERMSx#0#g'                      \
    +        -e 's#xPRUNED-SUFFIXx#.pruned#g'                \
    +        -e 's#xSUPERUSERx#1#g'                          \
    +        -e 's#xTARGETDIRx#/usr/local#g'                 \
    +        -e 's#xVERSIONx#2.16#g'                         \
    +        < graft.man > graft.1
    +
    + +
  7. If you're using the automounter under Solaris + 2.x, the installation process may not be able to directly + create the directory specified by TOP. If this is the case + then manually create this directory using whatever procedures + are appropriate for your operating system.

    + +

    For example, if the /usr/local mount point is under the + control of the automounter via an entry in the + auto_pkgs map:

    + +
    +    *   nfshost:/export/sparc-SunOS-5.5.1/usr/local/&
    +
    + +

    you'll need to create the Graft installation directory + by executing the following command on the machine nfshost: +

    + +
    +    mkdir /export/sparc-SunOS-5.5.1/usr/local/pkgs/graft-2.16
    +
    + +
  8. Install the Graft executable, manual page and + documentation by executing:

    + +
    +    make install
    +
    + +

    You should see output similar to:

    + +
    +    mkdir -p /usr/local/pkgs/graft-2.16/bin
    +    cp graft /usr/local/pkgs/graft-2.16/bin
    +
    +    for i in graft.1;                                              \
    +    do                                                             \
    +        manpage=`basename $i`;                                     \
    +        man=`expr $i : '.*\.\(.\)'`;                               \
    +        mkdir -p /usr/local/pkgs/graft-2.16/man/man$man;           \
    +        cp $i /usr/local/pkgs/graft-2.16/man/man$man/$manpage;     \
    +        chmod 644 /usr/local/pkgs/graft-2.16/man/man$man/$manpage; \
    +    done
    +
    +    for i in graft.html graft.pdf graft.ps graft.txt;              \
    +    do                                                             \
    +        mkdir -p /usr/local/pkgs/graft-2.16/doc;                   \
    +        cp doc/$i /usr/local/pkgs/graft-2.16/doc;                  \
    +        chmod 644 /usr/local/pkgs/graft-2.16/doc/$i;               \
    +        touch /usr/local/pkgs/graft-2.16/doc/.nograft;             \
    +    done
    +
    + +
+ +

Graft is now installed and ready to be used.

+ +

NOTE: If you make changes to your Graft installation at a +later date, please run the following commands:

+ +
+    make clean
+    make install
+
+ +

Failure to do this may result in a Graft manual page that does +NOT reflect your current configuration.

+ +

Creating RPM and DEB packages

+ +

Beginning with Graft 2.11 there is now the ability to create +RPM and Debian installation packages. Obviously you'll need one or more of +the rpmbuild and dpkg-deb packages installed on your +system.

+ +

After editing the Makefile to suit your environment simply run +the appropriate make command to create the binary installation +package in the current directory:

+ +
+    make rpm
+
+ +

or

+ +
+    make deb
+
+ +

The creation of these packages is somewhat experimental. Please let the +author know if you have issues.

+ +
+ +

Grafting Graft and Perl - the +bootstrap problem

+ +

If you are using an operating system that comes with Perl +5.x - such as RedHat or Ubuntu Linux - then you don't need to worry +about grafting Perl, so this section can be ignored.

+ +

However if you are a creator of an operating system +distribution then this section may be relevant.

+ +

Embedded into the Graft executable is the location of the +Perl executable. If you've understood the concept behind +Graft then this location may be the grafted location of +Perl rather than the true location of Perl.

+ +

This presents a dilemma when you come to graft both Graft +and Perl. You can't run the grafted location of the +Graft executable because it doesn't exist yet, and you can't run +the real location of the Graft executable because Perl +hasn't been grafted yet.

+ +

Assuming that Graft and Perl are installed in

+ +
+    /usr/local/pkgs/graft-2.16
+    /usr/local/pkgs/perl-5.18.2
+
+ +

you can resolve this dilemma by executing the following commands: +

+ +
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i graft-2.16
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i perl-5.18.2
+
+ +

This will graft both Graft and Perl from the +default package installation directory (as specified by +PACKAGEDIR in the Makefile) into your default target +directory (as specified by TARGETDIR in the Makefile). +

+ +

If you don't wish to use the default directories you can use the +following commands to graft the packages into /pkgs +instead of /usr/local for example:

+ +
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i -t /pkgs /usr/local/pkgs/graft-2.16
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i -t /pkgs /usr/local/pkgs/perl-5.18.2
+
+ +

Now both Graft and Perl have been grafted and any +other package can be grafted by executing the simpler command: +

+ +
+    graft -i package
+
+ +

The Graft distribution includes a program called +graftBootStrap.sh which allows you to easily graft both +Graft and Perl. It can be found in the contrib +directory of the distribution. Thanks to Gordon Rowell for providing it.

+ +

You may also find the -L command line option to be useful to +programmatically determine where Graft expects to find +Perl along with the default locations of its log file, target and +package directories. See the Information section +below for details.

+ +
+ +

Using Graft

+ +

Compiling Packages

+ +

Any packages you wish to place under the control of Graft should +be compiled and installed in such a way that any package dependent +files are referenced with the ACTUAL package installation directory +rather than the common area in which Graft will be creating +symbolic links. For example, ensure that Perl version +5.18.2 is looking for its library files in +/usr/local/pkgs/perl-5.18.2/lib/perl5 instead of +/usr/local/lib/perl5. This approach will allow you to easily +separate multiple versions of the same package without any problems.

+ +
+ +

Graft command line options

+ +

All of the details concerning actions, package locations and target +directories are passed to Graft on the command line. +(Graft 1.x used a configuration file. This has now been +deprecated in favour of a log file).

+ +

Graft's command line options can be summarised as:

+ +
+    graft -i [-P|u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -d [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -p [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -L
+
+ +

Graft has four basic actions:

+ +
    + +
  1. Install

    + +
    +    graft -i [-C] [-P|u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    + +
    + +
    -i +
    +

    Install symbolic links from the package + installation directory to the target directory. + Requires superuser privileges if + SUPERUSER was set to 1 in the + Makefile.

    + +
    -C +
    +

    If NEVERGRAFT was set to 1 + in the Makefile, disable the automatic + exclusion of files and/or directories whose + names exactly match the values specified by + GRAFT-NEVER in the Makefile.

    + +

    If NEVERGRAFT was set to 0 + in the Makefile, force the automatic + exclusion of files and/or directories whose + names exactly match the values specified by + GRAFT-NEVER in the Makefile.

    + +

    Can only be used with the -i option.

    + +

    This option is ignored for each grafted + directory, if the directory contains a + .nograft or .graft-include + file.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. If there + are no objects specified for + GRAFT-NEVER then this option will + be silently ignored and will not appear in the help + message nor in the manual page.

    + +
    -P +
    +

    Preserve modes and ownerships when creating new + directories or copying files if + PRESERVEPERMS was set to + 0 in the Makefile. Do not + preserve modes and ownerships if the option is not + provided on the command line.

    + +

    Do not preserve modes and ownerships when + creating new directories or copying files if + PRESERVEPERMS was set to + 1 in the Makefile. + Preserve modes and ownerships if the option is not + provided on the command line.

    + +

    Cannot be used with the -u option.

    + +

    This option will be silently ignored if the + effective user of Graft is not root.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. This + option will be silently ignored and will not appear + in the help message nor in the manual page if + SUPERUSER was set to + 0 in the Makefile.

    + +
    -u +
    +

    Superuser privileges are not required when + installing packages.

    + +

    Cannot be used with the -P option.

    + +

    This option is only available if + SUPERUSER was set to + 1 in the Makefile.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. This + option will be silently ignored and will not appear + in the help message nor in the manual page if + SUPERUSER was set to + 0 in the Makefile.

    + +
    -l log +
    +

    Specify an alternate log file instead of the + default specified by LOGFILE in the + Makefile. No logging is performed if + the -n option is used.

    + +

    Log entries have the form:

    + +
    +    878790215   1.10+   I    /usr/local/pkgs/cpio-2.4.2            /usr/local
    +    878888916   2.1     I    /usr/local/pkgs/gzip-1.2.4            /usr/local
    +    878888916   2.1     IC   /usr/local/pkgs/gzip-1.2.4/bin/gzip   invalid symlink
    +
    + +

    This shows that a development version of + graft (1.10+) was used to install + symbolic links from /usr/local/pkgs/cpio-2.4.2 + to /usr/local. A new version of + graft (2.1) was used to install symbolic + links from /usr/local/pkgs/gzip-1.2.4 to + /usr/local. The IC entry indicates + that a conflict occurred during this + installation - the file /usr/local/pkgs/bin/gzip + was a symbolic link to something other than + /usr/local/pkgs/gzip-1.2.4/bin/gzip.

    + +
    -n +
    +

    List actions but do not perform them. Implies + the very verbose option. Does not require + superuser privileges regardless of the value of + SUPERUSER in the Makefile.

    + +
    -v +
    +

    Be verbose.

    + +
    -V +
    +

    Be very verbose.

    + +
    -r /rootdir +
    +

    Use the fully qualified named directory as the + root directory for all graft operations. The source + directory, target directory and log file will all + be relative to this specific directory.

    + +

    Can only be used by the superuser.

    + +
    -s +
    +

    Stow/Depot compatibility mode. + Infer the Graft target directory from + each package installation directory in the + manner of Stow and Depot.

    + +

    Target directory is the dirname of the + dirname of the package installation + directory. (Yes that really is two + dirnames). So if the package + installation directory is

    + +
    +    /usr/local/depot/gzip-1.2.4
    +
    + +

    the package will be grafted into +

    + +
    +    /usr/local
    +
    + +

    Cannot be used with the -t option.

    + +
    -t target +
    +

    Override the default graft target + directory with target. The value + of target must be a fully + qualified directory and it must exist.

    + +

    Cannot be used with the -s option.

    + +
    package +
    +

    Install the named package. If package is + a fully qualified directory, use it as the + package installation directory. If + package is not a fully qualified + directory, prepend it with the value of + PACKAGEDIR as specified in the + Makefile.

    + +
    + +
    + +
  2. Delete

    + +
    +    graft -d [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    + +
    + +
    -d +
    +

    Delete symbolic links from the package target + directory to the package installation + directory. Requires superuser privileges if + SUPERUSER was set to 1 in the + Makefile.

    + +
    -D +
    +

    Delete empty directories if + DELETEOBJECTS was set to 0 in the + Makefile. If the option is not + provided on the command line, notify the user + that a directory has been emptied.

    + +

    Do not delete empty directories if + DELETEOBJECTS was set to 1 in the + Makefile. Notify the user that a + directory has been emptied. If the option is + not provided on the command line, delete empty + directories.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile.

    + +
    -u +
    +

    Superuser privileges are not required when + deleting packages.

    + +

    This option is only available if + SUPERUSER was set to + 1 in the Makefile.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. This + option will be silently ignored and will not appear + in the help message nor in the manual page if + SUPERUSER was set to + 0 in the Makefile.

    + +
    -l log +
    +

    Specify an alternate log file instead of the + default specified by LOGFILE in the + Makefile. No logging is performed if + the -n option is used.

    + +

    Log entries have the form:

    + +
    +    879126278       1.10+   D       /usr/local/pkgs/weblint-1.017     /usr/local
    +    879126278       1.10+   DC      /usr/local/pkgs/weblint-1.017/bin/weblint  file exists
    +    879126278       1.10+   DC      /usr/local/pkgs/weblint-1.017/man/man1/weblint.1  file exists
    +
    + +

    This shows that a development version of + graft (1.10+) was used to delete + symbolic links from /usr/local to + /usr/local/pkgs/weblint-1.017. The DC + entries indicate that conflicts occurred during + this action - the files + /usr/local/bin/weblint and + /usr/local/man/man1/weblint.1 already + exist.

    + +
    -n +
    +

    List actions but do not perform them. Implies + the very verbose option. Does not require + superuser privileges regardless of the value of + SUPERUSER in the Makefile.

    + +
    -v +
    +

    Be verbose.

    + +
    -V +
    +

    Be very verbose.

    + +
    -r /rootdir +
    +

    Use the fully qualified named directory as the + root directory for all graft operations. The source + directory, target directory and log file will all + be relative to this specific directory.

    + +

    Can only be used by the superuser.

    + +
    -s +
    +

    Stow/Depot compatibility mode. + Infer the Graft target directory from + each package installation directory in the + manner of Stow and Depot.

    + +

    Target directory is the dirname of the + dirname of the package installation + directory. (Yes that really is two + dirnames). So if the package + installation directory is

    + +
    +    /usr/local/depot/gzip-1.2.4
    +
    + +

    the package will be grafted into +

    + +
    +    /usr/local
    +
    + +

    Cannot be used with the -t option.

    + +
    -t target +
    +

    Override the default graft target + directory with target. The value + of target must be a fully + qualified directory and it must exist.

    + +

    Cannot be used with the -s option.

    + +
    package +
    +

    Delete the named package. If package is + a fully qualified directory, use it as the + package installation directory. If + package is not a fully qualified + directory, prepend it with the value of + PACKAGEDIR as specified in the + Makefile.

    + +
    + +
    + +
  3. Prune

    + +
    +    graft -p [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    + +
    + +
    -p +
    +

    Prune objects (files, links or directories) + from the package target directory that are in + conflict with the package installation + directory. Requires superuser privileges if + SUPERUSER was set to 1 in the + Makefile.

    + +
    -D +
    +

    Remove conflicting objects if + DELETEOBJECTS was set to 0 in the + Makefile. Rename conflicting objects + as object.pruned if the option + is not provided on the command line.

    + +

    Rename conflicting objects to + object.pruned if + DELETEOBJECTS was set to 1 in the + Makefile. Remove conflicting objects + if the option is not provided in the command + line.

    + +

    If a directory is to be removed and it is not + empty, it will be renamed as + dir.pruned and a suitable + warning message will be given regardless of the + sense of this flag.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile.

    + +
    -u +
    +

    Superuser privileges are not required when + pruning packages.

    + +

    This option is only available if + SUPERUSER was set to + 1 in the Makefile.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. This + option will be silently ignored and will not appear + in the help message nor in the manual page if + SUPERUSER was set to + 0 in the Makefile.

    + +
    -l log +
    +

    Specify an alternate log file instead of the + default specified by LOGFILE in the + Makefile. No logging is performed if + the -n option is used.

    + +

    Log entries have the form:

    + +
    +    879126283       1.10+   P       /usr/local/pkgs/weblint-1.017     /usr/local
    +
    + +

    This shows that a development version of + graft (1.10+) was used to delete objects + from /usr/local that were in conflict with + /usr/local/pkgs/weblint-1.017.

    + +
    -n +
    +

    List actions but do not perform them. Implies + the very verbose option. Does not require + superuser privileges regardless of the value of + SUPERUSER in the Makefile.

    + +
    -v +
    +

    Be verbose.

    + +
    -V +
    +

    Be very verbose.

    + +
    -r /rootdir +
    +

    Use the fully qualified named directory as the + root directory for all graft operations. The source + directory, target directory and log file will all + be relative to this specific directory.

    + +

    Can only be used by the superuser.

    + +
    -s +
    +

    Stow/Depot compatibility mode. + Infer the Graft target directory from + each package installation directory in the + manner of Stow and Depot.

    + +

    Target directory is the dirname of the + dirname of the package installation + directory. (Yes that really is two + dirnames). So if the package + installation directory is

    + +
    +    /usr/local/depot/gzip-1.2.4
    +
    + +

    the package will be grafted into +

    + +
    +    /usr/local
    +
    + +

    Cannot be used with the -t option.

    + +
    -t target +
    +

    Override the default graft target + directory with target. The value + of target must be a fully + qualified directory and it must exist.

    + +

    Cannot be used with the -s option.

    + +
    package +
    +

    Prune the named package. If package is + a fully qualified directory, use it as the + package installation directory. If + package is not a fully qualified + directory, prepend it with the value of + PACKAGEDIR as specified in the + Makefile.

    + +
    + +
  4. Information

    + +
    +    graft -L
    +
    + +
    + +
    -L +
    +

    This is a special mode and it overrides all + other command line arguments. When present + graft will display the + default locations for Perl, the + graft log file, the target directory, and the + package directory in a form suitable for creating + environment variables for Bourne like shells. The + output will appear on STDOUT as + follows:

    + +
    +    GRAFT_PERL=/usr/bin/perl
    +    GRAFT_LOGFILE=/var/log/graft
    +    GRAFT_TARGETDIR=/usr/local
    +    GRAFT_PACKAGEDIR=/usr/local/pkgs
    +
    + +

    You can set these environment variables using + one of the following methods.

    + +
    +    eval "$(graft -L)"    # modern shells such as bash, zsh etc
    +    eval "`graft -L`"     # older shells such as sh etc
    +
    + +
    + +
+ +
+ +

Testing the Graft Installation

+ +

Before creating the symbolic links from the target directory to +the package directory, you may wish to see what actions Graft +will perform. Execute the following command:

+ +
+    graft -i -n package-name
+
+ +

The -i option tells Graft to install the package and +the -n option tells Graft to report on its actions +without actually performing them. The default Graft target +directory will be used and the package installation directory will be +taken from the fully qualified package argument or the default value +will be prepended to the package argument if it is not fully qualified. +

+ +

Graft will report on the following actions:

+ + + +

If you were to test the installation of the kermit-5A190 +package you would execute the command:

+ +
+    graft -i -n kermit-5A190
+
+ +You should see output resembling: + +
+    Installing   links to /usr/local/pkgs/kermit-5A190 in /usr/local
+    Processing   /usr/local/pkgs/kermit-5A190
+    SYMLINK      /usr/local/README -> /usr/local/pkgs/kermit-5A190/README
+    NOP          /usr/local/pkgs/kermit-5A190/bin and /usr/local/bin are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    SYMLINK      /usr/local/bin/kermit -> /usr/local/pkgs/kermit-5A190/bin/kermit
+    SYMLINK      /usr/local/bin/wart -> /usr/local/pkgs/kermit-5A190/bin/wart
+    NOP          /usr/local/pkgs/kermit-5A190/man and /usr/local/man are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    NOP          /usr/local/pkgs/kermit-5A190/man/man1 and /usr/local/man/man1 are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    SYMLINK      /usr/local/man/man1/kermit.1 -> /usr/local/pkgs/kermit-5A190/man/man1/kermit.1
+    MKDIR        /usr/local/doc
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    SYMLINK      /usr/local/doc/ckccfg.doc -> /usr/local/pkgs/kermit-5A190/doc/ckccfg.doc
+    SYMLINK      /usr/local/doc/ckuins.doc -> /usr/local/pkgs/kermit-5A190/doc/ckuins.doc
+    SYMLINK      /usr/local/doc/ckc190.upd -> /usr/local/pkgs/kermit-5A190/doc/ckc190.upd
+    SYMLINK      /usr/local/doc/ckcker.upd -> /usr/local/pkgs/kermit-5A190/doc/ckcker.upd
+    SYMLINK      /usr/local/doc/ckaaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckaaaa.hlp
+    SYMLINK      /usr/local/doc/ckuaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckuaaa.hlp
+    NOP          /usr/local/pkgs/kermit-5A190/lib and /usr/local/lib are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    SYMLINK      /usr/local/lib/ckedemo.ini -> /usr/local/pkgs/kermit-5A190/lib/ckedemo.ini
+    SYMLINK      /usr/local/lib/ckeracu.ini -> /usr/local/pkgs/kermit-5A190/lib/ckeracu.ini
+    SYMLINK      /usr/local/lib/ckermit.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermit.ini
+    SYMLINK      /usr/local/lib/ckermod.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermod.ini
+    SYMLINK      /usr/local/lib/cketest.ini -> /usr/local/pkgs/kermit-5A190/lib/cketest.ini
+    SYMLINK      /usr/local/lib/ckevt.ini -> /usr/local/pkgs/kermit-5A190/lib/ckevt.ini
+    SYMLINK      /usr/local/lib/ckurzsz.ini -> /usr/local/pkgs/kermit-5A190/lib/ckurzsz.ini
+
+ +

This output shows you that most of the directories already exist +(indicated by the NOP flags). A symbolic link will be created +in the relevant target directory to each of the files in the +kermit-5A190 package. One directory exists in the +kermit-5A190 package that does not exist in the target - +doc. This directory will be created by Graft.

+ +

NOTE: If you are using the automounter you may not be +able to create the directory /usr/local/doc. You'll have to create +the directory on the NFS server under the file system in which it +really lives. You should be familiar with the peculiarities of the +automounter and your specific site configuration before creating +any directories directly under mount points used by the +automounter.

+ +
+ +

Installing Packages

+ +

Once you have ensured that Graft will perform the correct +actions, you can execute:

+ +
+    graft -i package-name
+
+ +

So to install kermit you would execute:

+ +
+    graft -i kermit-5A190
+
+ +

There will be no output from Graft unless it encounters a +conflict. If you wish to see more information you can specify one of +the verbose flags. For a minimum of output you can execute:

+ +
+    graft -i -v kermit-5A190
+
+ +

You should see the following output:

+ +
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+
+ +

If you choose the very verbose option by executing:

+ +
+    graft -i -V kermit-5A190
+
+ +

the output will be the same as that when the -n option was +used, however this time Graft will actually create the symbolic +links.

+ +
+    Installing   links to /usr/local/pkgs/kermit-5A190 in /usr/local
+    Processing   /usr/local/pkgs/kermit-5A190
+    SYMLINK      /usr/local/README -> /usr/local/pkgs/kermit-5A190/README
+    NOP          /usr/local/pkgs/kermit-5A190/bin and /usr/local/bin are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    SYMLINK      /usr/local/bin/kermit -> /usr/local/pkgs/kermit-5A190/bin/kermit
+    SYMLINK      /usr/local/bin/wart -> /usr/local/pkgs/kermit-5A190/bin/wart
+    NOP          /usr/local/pkgs/kermit-5A190/man and /usr/local/man are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    NOP          /usr/local/pkgs/kermit-5A190/man/man1 and /usr/local/man/man1 are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    SYMLINK      /usr/local/man/man1/kermit.1 -> /usr/local/pkgs/kermit-5A190/man/man1/kermit.1
+    NOP          /usr/local/pkgs/kermit-5A190/doc and /usr/local/doc are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    SYMLINK      /usr/local/doc/ckccfg.doc -> /usr/local/pkgs/kermit-5A190/doc/ckccfg.doc
+    SYMLINK      /usr/local/doc/ckuins.doc -> /usr/local/pkgs/kermit-5A190/doc/ckuins.doc
+    SYMLINK      /usr/local/doc/ckc190.upd -> /usr/local/pkgs/kermit-5A190/doc/ckc190.upd
+    SYMLINK      /usr/local/doc/ckcker.upd -> /usr/local/pkgs/kermit-5A190/doc/ckcker.upd
+    SYMLINK      /usr/local/doc/ckaaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckaaaa.hlp
+    SYMLINK      /usr/local/doc/ckuaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckuaaa.hlp
+    NOP          /usr/local/pkgs/kermit-5A190/lib and /usr/local/lib are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    SYMLINK      /usr/local/lib/ckedemo.ini -> /usr/local/pkgs/kermit-5A190/lib/ckedemo.ini
+    SYMLINK      /usr/local/lib/ckeracu.ini -> /usr/local/pkgs/kermit-5A190/lib/ckeracu.ini
+    SYMLINK      /usr/local/lib/ckermit.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermit.ini
+    SYMLINK      /usr/local/lib/ckermod.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermod.ini
+    SYMLINK      /usr/local/lib/cketest.ini -> /usr/local/pkgs/kermit-5A190/lib/cketest.ini
+    SYMLINK      /usr/local/lib/ckevt.ini -> /usr/local/pkgs/kermit-5A190/lib/ckevt.ini
+    SYMLINK      /usr/local/lib/ckurzsz.ini -> /usr/local/pkgs/kermit-5A190/lib/ckurzsz.ini
+
+ +

NOTE: In this case the /usr/local/doc directory was not +created by Graft because /usr/local is a mount point +controlled by the automounter. The doc directory was +created manually prior to executing Graft.

+ +
+ +

Bypassing package directories

+ +

You may have the need to place only part of a package under the control +of Graft. Examples of such occasions may be:

+ + + +

You can force Graft to bypass a directory by creating the file

+ +
+    package-name/dir/dir/.nograft
+
+ +

Using the second example above, if you were to create the file:

+ +
+    /usr/local/pkgs/perl-5.18.2/lib/perl5/.nograft
+
+ +

Graft would create directories and symbolic links for every file +and directory down to /usr/local/pkgs/perl-5.18.2/lib. The perl5 +directory and anything below it would not be created.

+ +
+ +

Including specific files and/or directories

+ +

There may be the occasional need to include specific files and/or +directories in a directory, rather than the entire directory tree itself. An +example of such an occurrence would be the case where a package +contains a number of subdirectories, only one of which is required to +be grafted.

+ +

You can force Graft to only include any number of files and/or +directories in a package directory by creating the file

+ +
+    .graft-include
+
+ +

in the same directory.

+ +

.graft-include will contain a list of file and/or directory names +- one per line - of the files and/or directories you wish to include.

+ +

Consider the a2ps package for example. When installed it +contains the following directories:

+ +
+    /usr/local/pkgs/a2ps-4.13b/bin
+    /usr/local/pkgs/a2ps-4.13b/etc
+    /usr/local/pkgs/a2ps-4.13b/include
+    /usr/local/pkgs/a2ps-4.13b/info
+    /usr/local/pkgs/a2ps-4.13b/lib
+    /usr/local/pkgs/a2ps-4.13b/man
+    /usr/local/pkgs/a2ps-4.13b/share
+
+ +

The only directory you wish to graft is the bin +directory. You could place a .nograft file in each of the other +directories, OR you could create a single .graft-include +file in /usr/local/pkgs/a2ps-4.13b/.graft-include. This file would +contain

+ +
+    bin
+
+ +

Now only the bin directory will be grafted.

+ +
+ +

Excluding specific files and/or directories

+ +

There may be the occasional need to exclude specific files and/or +directories from a directory, rather than the entire directory itself. An +example of such an occurrence would be the case where files from different +packages have the same name. Emacs and Xemacs use the same +names for a number of their configuration files for example.

+ +

You can force Graft to exclude any number of files and/or +directories from a package directory by creating the file

+ +
+    .graft-exclude
+
+ +

in the same directory.

+ +

.graft-exclude will contain a list of file and/or directory names +- one per line - of the files and/or directories you wish to exclude.

+ +

For example, if you did not wish the file

+ +
+    /usr/local/pkgs/sudo-1.5.3/etc/sudoers
+
+ +

to be grafted as

+ +
+    /usr/local/etc/sudoers
+
+ +

but you did want

+ +
+    /usr/local/pkgs/sudo-1.5.3/etc/visudo
+
+ +

to be grafted as

+ +
+    /usr/local/etc/visudo
+
+ +

you would create the file

+ +
+    /usr/local/pkgs/sudo-1.5.3/etc/.graft-exclude
+
+ +

and ensure its contents contained the line:

+ +
+    sudoers
+
+ +

NOTE: Any entries made in a .graft-exclude file will +override the same entries made in a .graft-include file. That is, +if a file or directory name is listen in both a .graft-exclude +and a .graft-include file, it will be excluded from the +graft.

+ +
+ +

Grafting configuration files

+ +

Beginning with Graft 2.11 there is now the ability to treat a +package directory as a repository for configuration files. In this case you +would place a .graft-config file in the package directory and any +files in that directory would be copied to the target +directory. Files in conflict would also be copied but would have a default +suffix of .new to ensure the existing file is not clobbered. +Conflict discovery is achieved using a simple 32-bit CRC check. This +feature has been added to assist operating system distributors manage +system configuration files, specifically it was added at the request of the +maintainer of the Dragora GNU/Linux +distribution.

+ +

Consider the following example. You may wish to upgrade the +openssh server as part of an upgrade to your distribution. In +order to preserve any local user modifications to the relevant +configuration files you would add a .graft-config file to the +package as follows:

+ +
+    /usr/local/pkgs/openssh-server-6.61/etc/default/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/init.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/init/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/network/if-up.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/pam.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/ufw/applications.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/lib/systemd/system/.graft-config
+
+ +

The other directories in the distribution would not require any control +files.

+ +

Imagine that the local administrator has made some changes to +/etc/pam.d/sshd such as adding additional authentication methods +to support two-factor authentication for example. As the distribution +maintainer you do not want to reverse this local change so when the local +administrator upgrades the distribution, Graft +copies the new /etc/pam.d/sshd file to +/etc/pam.d/sshd.new which allows the local administrator to merge +their changes with any new features supported by the upgrade.

+ +

To take full advantage of this feature you may need to explicitly set the +target directory as follows:

+ +
+    graft -i -t / openssh-server-6.61
+
+ +
+ +

Grafting part of a package

+ +

Some packages can be successfully used when only part of their +installation directory is grafted. Other packages are +recalcitrant and need some special hand holding which can only be +solved by grafting each section of the package separately.

+ +

The first scenario can be handled by either .nograft files or +partial grafts. Consider Perl version 5.18.2. +When installed in its own directory

+ +
+    /usr/local/pkgs/perl-5.18.2
+
+ +

there are three subdirectories

+ +
+    drwxr-sr-x   2 psamuel  bisg         512 Oct 30  1996 bin
+    drwxr-sr-x   3 psamuel  bisg         512 Oct 30  1996 lib
+    drwxr-sr-x   4 psamuel  bisg         512 Oct 30  1996 man
+
+ +

Everything in the lib directory is exclusive to Perl +and does not require grafting. Therefore, perl-5.18.2 can +be grafted using either of the following two methods:

+ +
+    touch /usr/local/pkgs/perl-5.18.2/lib/.nograft
+    graft -i perl-5.18.2
+
+ +or + +
+    graft -it /usr/local/bin perl-5.18.2/bin
+    graft -it /usr/local/man perl-5.18.2/man
+
+ +

Now let's consider a recalcitrant package - ObjectStore version +4.0.2.a.0. When installed in

+ +
+    /usr/local/pkgs/ostore-4.0.2.a.0
+
+ +

the following files and directories are available:

+ +
+    -rwxrwxr-x   1 pauln    one3        1089 Oct 31  1996 Copyright
+    drwxrwxrwx   8 pauln    one3         512 Oct  2  1996 common
+    drwxrwxrwx   6 pauln    one3         512 Oct 31  1996 sunpro
+    -rw-r-----   1 root     one3     1900544 Apr 29  1997 txn.log
+
+ +

The executable programs that need to be grafted are in +sunpro/bin and the manual pages that need to be grafted +are in common/man. Everything else in the package does not +need to be grafted. If the entire package was to be +grafted the result would be two directories that are not in the +regular $PATH and $MANPATH environment variables - namely +/usr/local/common/man and /usr/local/sunpro/bin, plus a host of +other directories that are not relevant for grafting. No amount +of .nograft and .graft-exclude juggling will solve +this problem.

+ +

The solution is to use two partial grafts:

+ +
+    graft -it /usr/local/bin ostore-4.0.2.a.0/sunpro/bin
+    graft -it /usr/local/man ostore-4.0.2.a.0/common/bin
+
+ +

Using this approach, the correct executables and manual pages are +available without the need to graft unnecessary files and +directories.

+ +
+ +

Deleting and/or Upgrading +Packages

+ +

If you wish to upgrade a package - let's assume you wish to upgrade +kermit from version 5A190 to version 6.0.192 - you'd follow +these steps.

+ +

Firstly, you'd compile and install kermit-6.0.192 in

+ +
+    /usr/local/pkgs/kermit-6.0.192
+
+ +

Once you'd tested it to your satisfaction, you'd need to delete the +symbolic links to the current grafted version. You can check +which actions Graft will perform by executing:

+ +
+    graft -d -n kermit-5A190
+
+ +

You'll see output similar to

+ +
+    Uninstalling links from /usr/local to /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    UNLINK       /usr/local/bin/kermit
+    UNLINK       /usr/local/bin/wart
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    UNLINK       /usr/local/man/man1/kermit.1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    UNLINK       /usr/local/doc/ckccfg.doc
+    UNLINK       /usr/local/doc/ckuins.doc
+    UNLINK       /usr/local/doc/ckc190.upd
+    UNLINK       /usr/local/doc/ckcker.upd
+    UNLINK       /usr/local/doc/ckaaaa.hlp
+    UNLINK       /usr/local/doc/ckuaaa.hlp
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    UNLINK       /usr/local/lib/ckedemo.ini
+    UNLINK       /usr/local/lib/ckeracu.ini
+    UNLINK       /usr/local/lib/ckermit.ini
+    UNLINK       /usr/local/lib/ckermod.ini
+    UNLINK       /usr/local/lib/cketest.ini
+    UNLINK       /usr/local/lib/ckevt.ini
+    UNLINK       /usr/local/lib/ckurzsz.ini
+    UNLINK       /usr/local/lib/.testing
+
+ +

If you're happy with the output from the test deletion you can delete +the grafted package. Once again, you'll only see output if a +failure occurs unless you use one of the verbose options.

+ +

If you execute:

+ +
+    graft -dV kermit-5A190
+
+ +

you'll see:

+ +
+    Uninstalling links from /usr/local to /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    UNLINK       /usr/local/bin/kermit
+    UNLINK       /usr/local/bin/wart
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    UNLINK       /usr/local/man/man1/kermit.1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    UNLINK       /usr/local/doc/ckccfg.doc
+    UNLINK       /usr/local/doc/ckuins.doc
+    UNLINK       /usr/local/doc/ckc190.upd
+    UNLINK       /usr/local/doc/ckcker.upd
+    UNLINK       /usr/local/doc/ckaaaa.hlp
+    UNLINK       /usr/local/doc/ckuaaa.hlp
+    EMPTY        /usr/local/doc is now empty. Delete manually if necessary.
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    UNLINK       /usr/local/lib/ckedemo.ini
+    UNLINK       /usr/local/lib/ckeracu.ini
+    UNLINK       /usr/local/lib/ckermit.ini
+    UNLINK       /usr/local/lib/ckermod.ini
+    UNLINK       /usr/local/lib/cketest.ini
+    UNLINK       /usr/local/lib/ckevt.ini
+    UNLINK       /usr/local/lib/ckurzsz.ini
+
+ +

NOTE: In this case the existence of an empty directory has been +discovered. If Graft empties a directory during a package +deletion, it will either notify you or delete the directory depending +on the combination of variables in the Makefile and command +line options. It's probably better practise not to automatically +delete empty directories as they may be used by other packages - such +as lock file directories for example.

+ +

Now you can remove the real package contents. (You may not wish +to do this immediately as some legacy systems may depend on features +provided by the older version or you may feel the need for further +testing before feeling confident that the old version can be removed): +

+ +
+    rm -rf /usr/local/pkgs/kermit-5A190
+
+ +

Now you can graft the new version of kermit. Execute:

+ +
+    graft -i -n kermit-6.0.192
+
+ +

to ensure that the grafting will proceed without error. Once +you are satisfied that this is the case you can graft the new +package by executing:

+ +
+    graft -i kermit-6.0.192
+
+ +
+ +

Transitioning a package to Graft +control

+ +

Graft can be used to easily transition a package from its +current installation in your target directory to a grafted +installation.

+ +

As an example, let's consider the package weblint version 1.017. +It consists of three files installed in:

+ +
+    /usr/local/bin/weblint
+    /usr/local/lib/global.weblintrc
+    /usr/local/man/man1/weblint.1
+
+ +

The first step is to create a new copy of the package in its own +directory:

+ +
+    /usr/local/pkgs/weblint-1.017
+
+ +

Ensure that any references to library files are now made to +/usr/local/pkgs/weblint-1.017/lib instead of /usr/local/lib. +

+ +

Test the new installation to ensure it behaves as expected.

+ +

Then prune the old files from /usr/local/* using:

+ +
+    graft -pV weblint-1.017
+
+ +

You'd expect to see output similar to:

+ +
+    Pruning      files in /usr/local which conflict with /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017/man
+    Processing   /usr/local/pkgs/weblint-1.017/man/man1
+    RENAME       /usr/local/man/man1/weblint.1
+    Processing   /usr/local/pkgs/weblint-1.017/bin
+    RENAME       /usr/local/bin/weblint
+    Processing   /usr/local/pkgs/weblint-1.017/lib
+    RENAME       /usr/local/lib/global.weblintrc
+
+ +

If you elected to delete conflicting files instead of renaming them +you'd use:

+ +
+    graft -pDV weblint-1.017
+
+ +

and you'd see output similar to:

+ +
+    Pruning      files in /usr/local which conflict with /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017/man
+    Processing   /usr/local/pkgs/weblint-1.017/man/man1
+    UNLINK       /usr/local/man/man1/weblint.1
+    Processing   /usr/local/pkgs/weblint-1.017/bin
+    UNLINK       /usr/local/bin/weblint
+    Processing   /usr/local/pkgs/weblint-1.017/lib
+    UNLINK       /usr/local/lib/global.weblintrc
+
+ +

Now the new version of weblint 1.017 can be grafted in +place:

+ +
+    graft -i weblint-1.017
+
+ +

The grafted version of weblint can now be tested.

+ +

If we renamed conflicting files, they can be removed once the +grafted weblint has been satisfactorily tested:

+ +
+    rm /usr/local/man/man1/weblint.1.pruned
+    rm /usr/local/bin/weblint.pruned
+    rm /usr/local/lib/global.weblintrc.pruned
+
+ +
+ +

Conflict Processing

+ +

Occasionally Graft will fail to completely install a package. This +occurs because Graft encounters a conflict. A conflict is defined as +one of the following possibilities:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Package Object + + Target Object +
+ directory + + not a directory +
+ file + + directory +
+ file + + file +
+ file + + symbolic link to something other than the package object +
+
+ +

If Graft encounters such a conflict during the installation of a +package it will report the conflict and exit.

+ +

Resolving the conflict depends on the nature of the conflict and is +beyond the scope of this discussion - however most conflicts will +either be the result of attempting to graft a package on top of +the same package actually installed in the target directory or a file +name clash between two (or more) different packages.

+ +

Conflicts arising from the pre-existence of a package in the target +directory can be resolved using graft's prune mechanism +described above in "Transitioning a +package to Graft control".

+ +

File name clash conflicts can be resolved by the use of either a +.nograft or +.graft-exclude file or by +grafting only part of a package as described above in +"Grafting part of a package". +

+ +

If Graft encounters a conflict while deleting a package, it will +report the conflict and continue deleting the remainder of the package. +In this way Graft will delete as much of the package as +possible. Conflicts that arise during deletion will probably be the +result of an incorrectly installed package or the installation of other +components of the same package without the use of Graft.

+ +

Conflict messages are written to standard error. All other messages +are written to standard output. To quickly determine if a package will +have any conflicts when grafted, redirect standard output to +/dev/null

+ +
+    graft -i -n package > /dev/null
+
+ +

If you don't see any output then you can safely assume that there will +be no conflicts when grafting this package.

+ +

See the comprehensive table above describing how +conflicts are handled for more details.

+ +
+ +

Exit Status

+ +

Graft will terminate with an exit status of either 0, 1, 2, 3 or 4 +under the following conditions:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Exit Status + + Condition +
+
+ 0 +
+
+ All operations succeeded. +
+
+ 1 +
+
+ A conflict occurred during installation. +
+
+ 2 +
+
+ Command line syntax was incorrect. +
+
+ 3 +
+
+ One or more packages listed on the command line does not + exist. Other valid packages listed on the command line were + processed correctly. +
+
+ 4 +
+
+ The log file /var/log/graft could not be updated. Usually a + result of a permission error. Any other error condition will + override this condition. +
+
+ +
+ +

Using Graft with other package +management tools

+ +

Most Unix vendors have released their own package management tools with +their operating systems. Examples of this are Solaris 2.x with its +SVR4 Package Manager pkgadd, RedHat Linux with its +RedHat Package Manager rpm, Ubuntu Linux (and other Debian +Linux derivatives) with its dpkg system and HP-UX 10.x with +its swinstall suite. Graft has been designed as an adjunct +to these package managers rather than a competitor. The author has used +Graft successfully with all of the operating systems mentioned here. +

+ + + +
+ +

Availability

+ +

The latest version of Graft should always be available from:

+ +
+    http://peters.gormand.com.au/Home/tools/graft
+
+ +
+ +

License

+ +

Graft is licensed under the terms of the GNU General Public +License, Version 2, June 1991.

+ +

You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or download +it from the Free Software Foundation's web site:

+ +
+    http://www.gnu.org/copyleft/gpl.html
+    http://www.gnu.org/copyleft/gpl.txt
+
+ + +
+ + + diff --git a/website/manual/en/html_node/about.html b/website/manual/en/html_node/about.html new file mode 100644 index 00000000..f73038ba --- /dev/null +++ b/website/manual/en/html_node/about.html @@ -0,0 +1,36 @@ + + + +Qi user guide + + + + + + + +Contents +Next +
+
+

Part I - Introducing Dragora

+ + + + +
+Contents +Next + + diff --git a/website/manual/en/html_node/configuration.html b/website/manual/en/html_node/configuration.html new file mode 100644 index 00000000..e8f5f537 --- /dev/null +++ b/website/manual/en/html_node/configuration.html @@ -0,0 +1,39 @@ + + + +Qi user guide + + + + + + + + +Contents +Previous +Next +
+
+

Part III - Configuration

+ + + + +
+Contents +Previous +Next + + diff --git a/website/manual/en/html_node/index.html b/website/manual/en/html_node/index.html new file mode 100644 index 00000000..0f8cf2d3 --- /dev/null +++ b/website/manual/en/html_node/index.html @@ -0,0 +1,65 @@ + + + +Dragora Documentation + + + + + + +

Dragora Documentation

+
+
Part I - Introducing Dragora +
+
Part II - Installation +
+
Part III - Configuration +
+
Part IV - Package management +
+
Qi user guide + +Graft - a package management utility + + + + diff --git a/website/manual/en/html_node/installation.html b/website/manual/en/html_node/installation.html new file mode 100644 index 00000000..ba73e5d4 --- /dev/null +++ b/website/manual/en/html_node/installation.html @@ -0,0 +1,39 @@ + + + +Qi user guide + + + + + + + + +Contents +Previous +Next +
+
+

Part II - Installation

+ + + + +
+Contents +Previous +Next + + diff --git a/website/manual/en/html_node/pkgmanagement.html b/website/manual/en/html_node/pkgmanagement.html new file mode 100644 index 00000000..24b4d6fd --- /dev/null +++ b/website/manual/en/html_node/pkgmanagement.html @@ -0,0 +1,3494 @@ + + + +Qi user guide + + + + + + + +Contents +Previous +
+
+

Part IV - Package management

+ + + + +

Qi user guide

+ +

Table of Contents

+
+ +
+

Next: +, Up: (dir)   [Contents][Index]

+
+

This user guide is for Qi (version 1.0, 15 April 2019).

+ + + + + + + + + + + + + +
+

Copyright (C) 2019 Matias Fonzo.

+

Qi’s home page can be found at +http://www.dragora.org. Send bug reports or suggestions to  +dragora-users@nongnu.org. + +

+
+

Next: +, Previous: , Up: Top   [ +Contents][Index]

+
+

1 Introduction

+ +

Qi is a simple but well-integrated package manager. It can create, + install, remove, and upgrade software packages. Qi produces binary + packages using recipes, which are files containing specific + instructions to build each package from source. Qi can manage multiple + packages under a single directory hierarchy. This method allows to + maintain a set of packages and multiple versions of them. This means + that Qi could be used as the main package manager or complement the + existing one.

+

Qi offers a friendly command line interface, a global configuration + file, a simple recipe layout to deploy software packages; also works + with binary packages in parallel, speeding up installations and + packages in production. The format used for packages is a simplified + but safe POSIX pax archive compressed with lzip.

+

Qi is a modern (POSIX-compliant) shell script released under the + terms of the GNU General Public License. There are only two major + dependencies for the magic: graft(1) and tarlz(1), the rest is expected + to be found in any Unix-like system.

+
+

Next: , Previous: , Up: Top   [Contents +][Index]

+
+

2 Invoking qi

+ +

This chapter describes the synopsis and command line options for + invoke Qi.

+
+
Usage: qi [OPTION]... [FILE]...
+
+
+

One mandatory option specifies the operation that ‘qi’ + should perform, other options are meant to detail how this operation + should be performed.

+

qi supports the following options to operate:

+
+
-b
+
+

Build package using recipe names.

+
+
-c
+
+

Create .tlz package from directory.

+
+
-d
+
+

Delete packages.

+
+
-i
+
+

Install packages.

+
+
-o
+
+

Resolve build order through .order files.

+
+
-u
+
+

Update packages (implies -i, -d and -p options).

+
+
-w
+
+

Warn about files that will be linked.

+
+
-x
+
+

Extract a package for debugging purposes.

+
+
+

There are common options between modes:

+
+
-N
+
+

Do not read the configuration file.

+

This will ignore any value in the qirc file.

+
+
-P <DIR>
+
+

Package directory for installations.

+

This option sets ‘${packagedir}’.

+

Only valid for -i, -d, or -u options.

+
+
-f
+
+

Force option.

+

This option can force the build of a recipe, or force the update of a + pre-existing package.

+

Only valid for -b, -u options.

+
+
-t <DIR>
+
+

Target directory for symbolic links.

+

This option sets ‘${targetdir}’.

+

Only valid for -i, -d, or -u options.

+
+
-k
+
+

Keep (don’t delete) ‘${srcdir}’ or ‘${destdir} +’ in build mode, keep (don’t delete) package directory in delete mode.

+

Only valid for -b, -d or -u options.

+
+
-p
+
+

Prune conflicts on package installations.

+

This option may proceed with the package installation if one or more + conflicts occur.

+
+
-r /rootdir
+
+

Use the fully qualified named directory as the root directory for all + qi operations. The target directory and package directory will be + relative to the specified directory, including the log file for graft.

+
+
-v
+
+

Be verbose (a 2nd -v gives more).

+
+
+

Options for build mode (-b):

+
+
-O <DIR>
+
+

Where the packages produced are written.

+

This option sets ‘${outdir}’.

+
+
-W <DIR>
+
+

Where archives, patches, and recipes are expected.

+

This option sets ‘${worktree}’.

+
+
-Z <DIR>
+
+

Where (compressed) sources will be found.

+

This option sets ‘${tardir}’.

+
+
-a
+
+

Architecture to use.

+

Default value is obtained via uname(1) as ‘uname -m’.

+
+
-j
+
+

Parallel jobs for the compiler.

+

If not specified, default sets to 1.

+
+
-1
+
+

Increment release number (‘${release}’ + 1).

+

It will be omitted if the -n option is being used.

+
+
-n
+
+

Don’t create a .tlz package.

+
+
-S
+
+

Selects the option to skip completed recipes.

+

This means, in interactive mode, when the dialog to summarize recipes + is shown.

+
+
+

Informative options:

+
+
-L
+
+

Print default directory locations.

+

This will print the target directory, package directory, working + tree, the directory for tarballs, and the output directory for the + packages produced.

+
+
-h
+
+

Display the help describing the options and then exit.

+
+
-V
+
+

Print the version number and license information. The version number + should be included in all bug reports.

+
+
+

Expected non-option arguments are package directories and regular + files: recipes or files ending in .tlz, .order. When FILE is -, qi can + read from the standard input. See examples in +Packages.

+
+

Next: , + Previous: +, Up: Top   [Contents][Index]

+
+

3 The qirc file

+ +

The global qirc file offers a way to define variables + and tools (such as a download manager) for default use. This file is + used by qi at runtime, e.g., to build, install, remove or upgrade + packages.

+

It has the following rules:

+ +

The command line options related to the package directory and target + directory plus some of the options used for the build mode can override + some values in qirc. See Invoking + qi.

+

The order in which qi looks for this file is:

+
    +
  1. ${HOME}/.qirc Effective user.
  2. +
  3. ${sysconfdir}/qirc’ System-wide.
  4. +
+

If you intend to run qi as effective user, the file ‘ +${sysconfdir}/qirc’ could be copied to ${HOME}/.qirc + setting the paths for ‘${packagedir}’ and ‘ +${targetdir}’ according to the $HOME.

+
+

Next: , + Previous: , Up: Top   [Contents][Index]

+
+

4 Packages

+ +

A package is a suite of programs usually distributed in binary form + which may also contain manual pages, documentation, or any other file + associated to a specific software.

+

The package format used by qi is a simplified POSIX pax archive + compressed with lzip. The file extension for packages is ‘.tlz +’.

+

Both package installation and package de-installation are managed + using two important (internal) variables: ‘${packagedir}’ + and ‘${targetdir}’, these values can be changed in the + configuration file or via options.

+

${packagedir}’ is a common directory tree where the + package contents will be decompressed (will reside).

+

${targetdir}’ is a target directory where the links + will be made by graft(1) taking ‘${packagedir}/package_name +’ into account.

+

Packages are installed in self-contained directory trees and symbolic + links from a common area are made to the package files. This allows + multiple versions of the same package to coexist on the same system.

+ +

4.1 Package conflicts

+ +

All the links to install or remove a package are handled by graft(1). + Since multiple packages can be installed or removed at the same time, + certain conflicts may arise between the packages.

+

graft1 defines a + CONFLICT as one of the following conditions:

+ +

The default behavior of qi for an incoming package is to ABORT if a + conflict arises. When a package is going to be deleted, qi tells to + graft(1) to remove those parts that are not in conflict, leaving the + links to the belonging package. This behavior can be forced if the -p + option is given.

+ +

4.2 Installing packages

+ +

To install a single package, simply type:

+
+
qi -i coreutils-8.30-i586+1.tlz
+
+
+

To install multiple packages at once, type:

+
+
qi -i gcc-8.3.0-i586+1.tlz rafaela-2.2-i586+1.tlz ...
+
+
+

Warn about the files that will be linked:

+
+
qi -w bash-5.0-i586+1.tlz
+
+
+

This is to verify the content of a package before installing it.

+

See the process of an installation (very verbose):

+
+
qi -i -v mariana-3.0-i586+1.tlz
+
+
+

A second -v gives more.

+

Installing package in a different location:

+
+
qi -r /media/floppy -i lzip-1.21-i586+1.tlz
+
+
+

The -r option assumes ‘${targetdir}’ and ‘ +${packagedir}’. See:

+
+
qi -r /home/selk -P /pkgs -t / -i lzip-1.21-i586+1.tlz
+
+
+

In this case the content of "lzip-1.21-i586+1.tlz" will be + decompressed into ‘/home/selk/pkgs/lzip-1.21-i586+1’. + Assuming that the main binary for lzip is under ‘ +/home/selk/pkgs/lzip-1.21-i586+1/usr/bin/’ the target for + "usr/bin" will be created at ‘/home/selk’. Considering + that you have exported the PATH as ‘${HOME}/usr/bin +’, now the system is able to see the recent lzip.

+

Installing from a list of packages using standard input:

+
+
cat FILELIST.txt | qi -i -
+
+
+

The list of packages must contain full path names to be passed in the + installation, e.g.: + /var/cache/qi/packages/x86_64/devel/tcl-8.6.9-x86_64+1.tlz + /var/cache/qi/packages/x86_64/devel/tk-8.6.9.1-x86_64+1.tlz + /var/cache/qi/packages/x86_64/devel/vala-0.42.3-x86_64+1.tlz

+ +

4.3 Removing packages

+ +

To remove a package, simply type:

+
+
qi -d xz-5.2.4-i586+1.tlz
+
+
+

Delete mode will match the package name using ‘${packagedir} +’ as prefix. For example, if the value of ‘${packagedir}’ + is set to /usr/local/pkgs, this will be equal to:

+
+
qi -d /usr/local/pkgs/xz-5.2.4-i586+1
+
+
+

Detailed output (very verbose):

+
+
qi -d -v /usr/local/pkgs/xz-5.2.4-i586+1
+
+
+

A second -v gives more.

+

By default the delete mode does not preserve a package directory + after removing its links from ‘${targetdir}’, but this + behavior can be changed if the -k option is passed:

+
+
qi -d -k /usr/local/pkgs/lzip-1.21-i586+1
+
+
+

This means that the links to the package can be reactivated, later:

+
+
cd /usr/local/pkgs && graft -i lzip-1.21-i586+1
+
+
+

Removing package from a different location:

+
+
qi -r /home/cthulhu -P /pkgs -t / -d xz-5.2.4-i586+1
+
+
+

Removing a package using standard input:

+
+
echo "vala-0.42.3-x86_64+1" | qi -d -
+
+
+

This will match with the package directory.

+ +

4.4 Upgrading packages

+ +

The upgrade mode inherits the properties of the installation and + removal process. To make sure that a package is updated, the package is + installed in a temporary directory taking ‘${packagedir}’ + into account. Once the incoming package is pre-installed, qi can + proceed to search and delete packages that have the same name + (considered as previous ones). Finally, the package is re-installed at + its final location and the temporary directory is removed.

+

To upgrade a package, just type:

+
+
qi -u gcc-9.0.1-i586+1.tlz
+
+
+

This will proceed to update "gcc-9.0.1-i586+1" removing other + versions of "gcc" (if any).

+

If you want to keep the package directories of versions found during + the upgrade process, just pass:

+
+
qi -u -k gcc-9.0.1-i586+1.tlz
+
+
+

To see the upgrade process (very verbose):

+
+
qi -u -v gcc-9.0.1-i586+1.tlz
+
+
+

A second -v gives more.

+

To force the upgrade of an existing package:

+
+
qi -u -f gcc-9.0.1-i586+1.tlz
+
+
+

4.4.1 Package blacklist

+ +

To implement general package facilities, either to install, remove or + maintain the hierarchy of packages in a clean manner, qi makes use of + the pruning operation via graft(1):

+

There is a risk if those are crucial packages for the proper + functioning of the system, because it implies the deactivation of + symbolic from the target directory, especially when + transitioning an incoming package into its final location during + upgrade.

+

A blacklist of package names has been devised for the case where a + user decides to upgrade all packages in the system, or just the crucial + ones, such as the C library.

+

The blacklist is related to the upgrade mode only, consists in + installing a package instead of updating it or removing previous + versions of it; the content of the package will be updated over the + existing content at ‘${packagedir}’, while the existing + links from ‘${targetdir}’ will be preserved. A pruning of + links will be carried out in order to re-link possible differences with + the recent content, this helps to avoid leaving dead links in the + target directory.

+

Since the upgrade mode is also used to install a new package, the + mechanism for blacklist is to install a declared package if it does not + already exist. If it already exists, it is verified that the binary + package is newer than the package directory in order to perform an + update.

+

Package names for the blacklist can be set from the configuration + file.

+
+

Next: +, Previous: , + Up: Top   [Contents][Index]

+
+

5 Recipes

+ +

A recipe is a file telling qi what to do. Most often, the recipe + tells qi how to build a binary package from a source tarball.

+

A recipe has two parts: a list of variable definitions and a list of + sections. By convention, the syntax of a section is:

+
+
section_name()
+{
+    section lines
+}
+
+
+

The section name is followed by parentheses, one newline and an + opening brace. The line finishing the section contains just a closing + brace. The section names or the function names currently recognized are + ‘build’.

+

The ‘build’ section is an augmented shell script. This + is the main section (or shell function) which contains + the instructions to build and produce a package.

+ +

5.1 Variables

+ +

A "variable" is a shell variable defined either in +qirc or in a recipe to represent a string of text, called the + variable’s "value". These values are substituted by explicit request in + the definitions of other variables or in calls to external commands.

+

Variables can represent lists of file names, options to pass to + compilers, programs to run, directories to look in for source files, + directories to write output to, or anything else you can imagine.

+

Definitions of variables in qi have four levels of precedence. + Options which define variables from the command-line override those + specified in the qirc file, while variables defined in the + recipe override those specified in qirc, taking priority + over those variables set by command-line options. Finally, the + variables have default values if they are not defined anywhere.

+

Options that set variables through the command-line can only + reference variables defined in qirc and variables with + default values.

+

Definitions of variables in qirc can only reference + variables previously defined in qirc and variables with + default values.

+

Definitions of variables in the recipe can only reference variables + set by the command-line, variables previously defined in the recipe, + variables defined in qirc, and variables with default + values.

+ +

5.2 Special variables

+ +

There are variables which can only be set using the command line + options or via qirc, there are other special variables + which can be defined or redefined in a recipe. See the following + definitions:

+

outdir’ is the directory where the packages produced + are written. This variable can not be redefined in the recipe. Default + sets to ‘/var/cache/qi/packages’.

+

worktree’ is the working tree where archives, patches, + and recipes are expected. This variable can not be redefined in the + recipe. Default sets to ‘/usr/src/qi’.

+

tardir’ is defined in the recipe to the directory where + the tarball containing the source can be found. The full name of the + tarball is composed as ‘${tardir}/$tarname’. Its value is + available in the recipe as ‘${tardir}’; a value of . for ‘ +tardir’ sets it to the value of CWD (Current Working Directory), + this is where the recipe lives.

+

arch’ is the architecture to compose the package name. + Its value is available in the recipe as ‘${arch}’. Default + value is the output of ‘uname -m’.

+

jobs’ is the number of parallel jobs to pass to the + compiler. Its value is available in the recipe as ‘${jobs} +’. The default value is 1.

+

The two variables ‘${srcdir}’ and ‘${destdir} +’ can be set in the recipe, as any other variable, but if they are not, + qi uses default values for them when building a package.

+

srcdir’ contains the source code to be compiled, and + defaults to ‘${program}-${version}’. ‘destdir +’ is the place where the built package will be installed, and defaults + to ‘${TMPDIR}/package-${program}’.

+

If ‘pkgname’ is left undefined, the special variable ‘ +program’ is assigned by default. If ‘pkgversion’ is + left undefined, the special variable ‘version’ is assigned + by default.

+

pkgname’ and ‘pkgversion’ along with: ‘ +version’, ‘arch’, and ‘release’ are + used to produce the name of the package in the form: ‘ +${pkgname}-${pkgversion}-${arch}+${release}.tlz

+

A special variable called ‘replace’ can be used to + declare package names that will be replaced at the time of + installation.

+

A typical recipe contains the following variables:

+ +

Obtaining sources over the network must be declared in the recipe + using the ‘fetch’ variable. Use double quotes for + separated values.

+

The variables ‘netget’ and ‘rsync’ can be + defined in qirc to establish a network downloader in order + to get the sources. If they are not defined, qi uses default values:

+

netget’ is the general network downloader tool, + defaults sets to ‘wget -c -w1 -t3 --no-check-certificate’.

+

rsync’ is the network tool for sources containing the + prefix for the RSYNC protocol, default sets to ‘rsync -v -a -L -z + -i --progress’.

+

The variable ‘description’ is used to print the package + description when a package is installed.

+

A description has two parts: a brief description, and a long + description. By convention, the syntax of ‘description’ + is:

+
+
description="
+Brief description.
+
+Long description.
+"
+
+
+

The first line of the value represented is a brief description of the + software (called "blurb"). A blank line separates the brief + description from the long description, which should + contain a more descriptive description of the software.

+

An example looks like:

+
+
description="
+The GNU core utilities.
+
+The GNU core utilities are the basic file, shell and text manipulation
+utilities of the GNU operating system.  These are the core utilities
+which are expected to exist on every operating system.
+"
+
+
+

Please consider a length limit of 78 characters as maximum, because + the same one would be used on the meta file creation. See +The meta file section.

+

The ‘homepage’ variable is used to declare the main site + or home page:

+
+
homepage=http://www.gnu.org/software/gcc
+
+
+

The variable ‘license’ is used for license information2. Some code in the program can be covered + by license A, license B, or license C. For "separate licensing" or + "heterogeneous licensing", we suggest using | for a + disjunction, & for a conjunction (if that ever happens + in a significant way), and comma for heterogeneous licensing. Comma + would have lower precedence, plus added special terms.

+
+
license="LGPL, GPL | Artistic + added permission"
+
+
+

5.3 Writing recipes

+ +

Originally, qi was designed for the version 3 of Dragora GNU/Linux + (this does not mean that you can use it in another distribution). + Therefore we will put here some references where you will be able to + find real and complete examples to write good recipes:

+

+http://git.savannah.nongnu.org/cgit/dragora.git/tree/recipes. +http://notabug.org/dragora/dragora/src/master/recipes.

+

You can also check the "doc" directory in the distribution sources of + qi for some examples.

+ +

5.4 Building packages

+ +

A recipe is any valid regular file. Qi sets priorities for reading a + recipe, the order in which qi looks for a recipe is:

+
    +
  1. Current working directory.
  2. +
  3. If the specified path name does not contain "recipe" as the last + component. Qi will complete it by adding "recipe" to the path name.
  4. +
  5. If the recipe is not in the current working directory, it will be + searched under ‘${worktree}/recipes’. The last component + will be completed adding "recipe" to the specified path name.
  6. +
+

To build a single package, type:

+
+
qi -b x-apps/xterm
+
+
+

Multiple jobs can be passed to the compiler to speed up the build + process:

+
+
qi -b -j3 x-apps/xterm
+
+
+

Update or install the package produced (if it is not already + installed) when finish:

+
+
qi -b -j3 -u x-apps/xterm
+
+
+

Only process a recipe but do not create the binary package:

+
+
qi -b -n dict/aspell
+
+
+

The options -i or -u have no effect when -n is given.

+

This can be useful to inspect the build process of recipe:

+

qi -b -k -n dict/aspell 2>&1 | tee aspell-buildlog.txt

+

The -k option could preserve the source directory and the destination + directory for later inspection. A log file of the build process will be + created redirecting both, standard error and standard output to tee(1).

+ +

5.5 Variables from the environment

+ +

Qi has environment variables which can be used at build time:

+

The variable TMPDIR sets the temporary directory for + sources, which is used for package extractions (see +Examining packages) and is prepended to the value of ‘ +${srcdir}’ and ‘${destdir}’ in build mode. By + convention its default value is equal to ‘/usr/src/qi/build +’.

+

The variables QICFLAGS, QICXXFLAGS, and +QILDFLAGS have no effect by default. The environment variables + such as CFLAGS, CXXFLAGS, and LDFLAGS + are unset at compile time:

+

Recommended practice is to set variables in the command line of ‘ +configure’ or make(1) instead of exporting to the + environment. As follows:

+
+

Variables not defined in a site shell script can be set in the + environment passed to configure. However, some packages may run + configure again during the build, and the customized values of these + variables may be lost. In order to avoid this problem, you should set + them in the configure command line, using ‘VAR=value’. For + example:

+

./configure CC=/usr/local2/bin/gcc

+

+http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Defining-Variables.html +

+
+

Indeed, while configure can notice the definition of CC in ‘ +./configure CC=bizarre-cc’, it is impossible to notice it in ‘ +CC=bizarre-cc ./configure’, which, unfortunately, is what most + users do.

+

[...]

+

configure: error: changes in the environment can compromise the + build.

+

+http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Setting-Output-Variables.html +

+
+

It is not wise for makefiles to depend for their functioning on + environment variables set up outside their control, since this would + cause different users to get different results from the same makefile. + This is against the whole purpose of most makefiles.

+

+http://gnu.org/software/make/manual/make.html#Environment

+
+

5.6 The meta file

+ +

The "meta file" is a regular file created during the build mode, it + contains information about the package such as program name, program + version, release, fetch address, description, and other minor data + extracted from processed recipes. The name of the file is generated as + ‘${full_pkgname}.tlz.txt’, and its purpose is to reflect + essential information to the user without having to look inside the + package content.

+

The content of a meta file looks like:

+
+
#
+# The Bourne Again SHell.
+#
+# Bash is an sh-compatible shell that incorporates useful features from
+# the Korn shell (ksh) and C shell (csh).  It is intended to conform to
+# the IEEE POSIX P1003.2/ISO 9945.2 shell and tools standard.
+#
+# It offers functional improvements over sh for both programming and
+# interactive use.
+#
+
+QICFLAGS="-g0 -Os -mtune=generic -pipe"
+QICXXFLAGS="-g0 -Os -mtune=generic -pipe"
+QILDFLAGS="-s"
+program=bash
+version=5.0
+release=1
+blurb="The Bourne Again SHell."
+homepage="http://www.gnu.org/software/bash"
+license="GPLv3+"
+fetch="ftp://ftp.gnu.org/gnu/bash/bash-5.0.tar.gz"
+replace=""
+
+
+

Package descriptions are extracted from the variable ‘ +description’: each line is interpreted literally and + pre-formatted to fit in (exactly) 80 columns, plus the + character ‘#’ and a space is prefixed to every line.

+

In addition to the Special variables, there are implicit variables + such as ‘blurb’:

+

The ‘blurb’ variable is related to the special variable + ‘description’. Its value is composed using the first + (substantial) line of ‘description’, mentioned as the + "brief description".

+
+

Next: , Previous: , Up: Top   [Contents][Index]

+
+

6 Order files

+ +

The order mode has the purpose of resolving the build order through + .order files. An order file contains a list of recipe names, by default + does not perform any action other than to print a resolved list in + descending order. For example, if a depends on + b and c, and c depends on + b as well, the file might look like:

+
+
a: c b
+b:
+c: b
+
+
+

Each letter represents a recipe name, complete dependencies for the + first recipe name are listed in descending order, which is printed from + right to left, and removed from left to right:

+

OUTPUT

+
+
b
+c
+a
+
+
+

Blank lines, colons and parentheses are simply ignored. Comment lines + beginning with ‘#’ are allowed.

+

An order file could be used to build a series of packages, for + example, if the content is:

+
+
# Image handling libraries
+
+libs/libjpeg-turbo: devel/nasm
+x-libs/jasper: libs/libjpeg-turbo
+libs/tiff: libs/libjpeg-turbo
+
+
+

To proceed with each recipe, we can type:

+
+
qi -o imglibs.order | qi -b -i -
+
+
+

The output of ‘qi -o imglibs.order’ tells to qi in which + order it should build the recipes:

+
+
devel/nasm
+libs/libjpeg-turbo
+x-libs/jasper
+libs/tiff
+
+
+
+

Next: , Previous: , Up: Top   [Contents][Index]

+
+

7 Creating packages

+ +

The "creation mode" is an internal function of qi to make new Qi + compatible compatible packages, the creation mode is selected by the -c + option. A package is produced using the contents of the Current + Directory, and the package file is written out.

+
+
Usage: qi -c [OUTPUT/packagename.tlz]...
+
+
+

The argument for the file name to be written must contain a fully + qualified named directory as the output directory where the package + produced will be written. The file name should be composed using the + full name: name-version-architecture+release.tlz

+

EXAMPLE

+
+
cd /usr/local/pkgs
+cd claws-mail-3.17.1-x86_64+1
+qi -c /var/cache/qi/packages/x86_64/local/claws-mail-3.17.1-x86_64+1.tlz
+
+
+

In this case, the package "claws-mail-3.17.1-x86_64+1.tlz" will be + written into ‘/var/cache/qi/packages/x86_64/local/’.

+

All packages produced are complemented by a checksum file (.sha256).

+
+

Next: +, Previous: , Up: Top +   [ +Contents][Index]

+
+

8 Examining packages

+ +

The "extraction mode" serves to examine binary packages for debugging + purposes. The extraction mode is selected by the -x option. It + decompresses a package into a single directory, verifying its integrity + and preserving its properties.

+
+
Usage: qi -x [packagename.tlz]...
+
+
+

EXAMPLE

+
+
qi -x mksh-R56c-x86_64+1.tlz
+
+
+

This action will put the content of "mksh-R56c-x86_64+1.tlz" into a + single directory, this will be a private directory for the user who

+

requested the action, creation mode will be equal to + u=rwx,g=,o= (0700). The package content will reside on this + location, default mask to deploy the content will be equal to + u=rwx,g=rwx,o=rwx (0000).

+

The creation of the custom directory is influenced by the value of + the TMPDIR variable.

+
+

Next: , Previous: + , Up: Top   [Contents][Index]

+
+

9 Exit status

+ +

All the exit codes are described in this chapter.

+
+
0
+
+

Successful completion (no errors).

+
+
1
+
+

Minor common errors:

+
    +
  • - Help usage on illegal options or required arguments.
  • +
  • - Program needed by qi (prerequisite) is not available.
  • +
+
+
2
+
+

Command execution error:

+

This code is used to return the evaluation of external commands and + shell arguments in case of error.

+
+
3
+
+

Integrity check error for compressed files.

+

Compressed files means:

+
    +
  • - Tarball files from tar(1). Supported extensions: .tar, .tar.gz, + .tgz, .tar.Z, .tar.bz2, .tbz2, .tbz, .tar.xz, .txz
  • +
  • - Tarball files from tarlz(1). Supported extensions: .tar.lz, .tlz
  • +
  • - Zip files from unzip(1). Supported extensions: .zip, .ZIP
  • +
  • - Gzip files from gzip(1). Supported extensions: .gz, .Z
  • +
  • - Bzip2 files from bzip2(1). Supported extensions: .bz2
  • +
  • - Lzip files from lzip(1). Supported extensions: .lz
  • +
  • - Xz files from xz(1). Supported extensions: .xz
  • +
+
+
4
+
+

File empty, not regular, or expected.

+

Commonly, it is expected:

+
    +
  • - An argument for the mode of operation.
  • +
  • - A readable file or directory.
  • +
  • - A binary package (.tlz).
  • +
  • - A valid recipe.
  • +
  • - An order file (.order).
  • +
  • - A protocol supported by the network downloader tool.
  • +
  • - A checksum file (.sha256).
  • +
+
+
5
+
+

Empty or not defined variable:

+

This code is used to report empty or undefined variables; usually, + variables coming from a recipe or assigned arrays that are tested.

+
+
6
+
+

Package already installed:

+

The package directory for an incoming .tlz package already exists.

+
+
10
+
+

Network manager error:

+

This code is used if the network downloader tool fails for some + reason.

+
+
+
+

Previous: , Up: Top   [Contents][Index]

+
+

Index

+ + +
Jump to:   +C   E +   H +   I   M   +P   R +   S +   T   V   +W  
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  + Section
+
C
+configuration file:  +The qirc file
+
E
+environment variables:  +Recipes
exit codes +: Exit status
+
H
+handling build order:  +Order files
+
I
introduction +: Introduction +
invocation +: Invoking qi
+
M
+managing packages:  +Packages
+
P
package + blacklist:  +Packages
package + build: Recipes +
package + conflicts:  +Packages
package + creation:  +Creating packages
+package de-installation:  +Packages
+package examination:  +Examining packages
+package installation:  +Packages
package + upgrade:  +Packages
+
R
recipes:Recipes
+
S
special + variables:  +Recipes
+
T
the meta + file: Recipes
+
V
variables:Recipes
+
W
writing + recipes: Recipes +
+
+ + +
Jump to:   +C   E +   H +   I   M   +P   R +   S +   T   V   +W  
+
+
+

Footnotes

+

(1)

+

The official guide for Graft can be found at +http://peters.gormand.com.au/Home/tools/graft/graft.html.

+

(2)

+

The proposal for ‘license’ was made by Richard M. + Stallman at +http://lists.gnu.org/archive/html/gnu-linux-libre/2016-05/msg00003.html +.

+
+
+
+

Graft - a package management utility

+
+

Prepared by Peter Samuel +<peter.r.samuel@gmail.com>

+

$Revision: 2.16 $

+

$Date: 2018/04/16 14:54:07 $

+
+

graft: To insert (a graft) in a branch or stem + of another tree; to propagate by insertion in another stock; also, to + insert a graft upon. To implant a portion of (living flesh or skin) in + a lesion so as to form an organic union. To join (one thing) to another + as if by grafting, so as to bring about a close union.

+
+
+

Contents

+ +
+

Introduction

+

Graft provides a mechanism for managing multiple packages + under a single directory hierarchy. It was inspired by both Depot + (Carnegie Mellon University) and Stow (Bob Glickstein).

+

For the purposes of this discussion a package is defined as + a suite of programs and files that make up an individual product. For + example, the package known as gcc consists of the + compiler and preprocessor programs, include files, manual pages and any + other associated file or program. The concept of a package + should not be confused with some vendor's definitions that are - by + this definition - actually collections of packages.

+

Special thanks to Gordon Rowell, Charles Butcher, Charlie Brady, + Robert Maldon and Matias A. Fonzo for design suggestions and + contributions.

+
+

Rationale

+

In any reasonably large environment, many software packages will be + installed. The installation location for these packages usually follows + one of three rationales - each with its own advantages and drawbacks:

+
    +
  1. +

    Each package is isolated from all other packages by installing it + into a self contained directory tree. All binaries, manual pages, + library and configuration files are stored under a single directory + tree. This directory tree contains NO other files which are not the + exclusive domain of the package in question.

    +

    This method makes package demarcation obvious. As each package is + self contained, identification of any file within a package is + immediately apparent.

    +

    Multiple versions of packages can be installed fairly easily to + accommodate acceptance testing of new versions and/or legacy systems.

    +

    However, the use of individual package directories can lead to VERY + long $PATH and $MANPATH environment + variables. Some shells may not be able to handle such long variables. + Whenever a new package is added, each user MUST update their + $PATH and $MANPATH to make the package + available.

    +
  2. +
  3. +

    Packages are installed under a common directory tree. Binaries for + all packages are grouped in a single directory, manual pages for all + packages in another directory and so on.

    +

    This method eliminates the need for continually updating long + $PATH variables for each user. As soon as a package is placed + into the common 'bin' directory it is immediately available to + all users (after a shell rehash if necessary).

    +

    However, when a package is to be updated it is often very difficult + to isolate all the files related to a particular package if they are + intermingled with unrelated files.

    +
  4. +
  5. +

    A combination of methods (1) and (2).

    +
  6. +
+

In an effort to maximise the advantages and minimise the + disadvantages, Depot, Stow and Graft adopt a + similar philosophy:

+
+

Packages are installed in self contained directory trees and + symbolic links from a common area are made to the package files.

+
+

This approach allows multiple versions of the same package to + co-exist on the one system. One version is the commonly available + version and symbolic links will be made to this version. New versions + can be tested and once acceptable can replace the current commonly + available version. Older versions can still be used for legacy systems + by using the 'real' path name to the package instead of the ' +common' path name.

+

The size and complexity of environment variables such as + $PATH and $MANPATH is minimised because only + the common area is required. Any special cases can also be accommodated + but these will usually be in the minority when compared with the number + of commonly available packages.

+
+

Research

+

Note: Development of Graft began in late + 1996. The comments regarding the packages listed below reflect their + functionality and behaviour at that time and may not necessarily + reflect their current functionality and behaviour.

+

As stated earlier, Graft was inspired by Depot and + Stow. Both these systems were examined and finally rejected for + the following reasons:

+
+
Depot +ftp://ftp.andrew.cmu.edu/pub/depot/depot.tar.gz
+
+

Depot is very flexible yet cumbersome.

+

It requires a database file to be created which provides a snapshot + of the current state of both the package repository and the Depot + target. It is possible to inadvertently destroy the package repository + if the database is damaged.

+

Depot assumes "ownership" of the target area, + making it almost impossible to accommodate packages that are not under + the control of Depot. ("Ownership" in this case means + that Depot assumes ALL files in the target area will be under + the control of Depot. It does not imply that Depot + modifies Unix file permissions).

+

Because of Depot's assumed ownership it is + difficult for other packages not under the control of Depot to + be placed in the same target area.

+

Depot attempts to impose a fixed package repository + relative to the package target. It assumes that all packages will be + stored under 'dir/depot/package' and the + target will be 'dir'. This can be overridden on the + command line but the internals of Depot make this mechanism + cumbersome.

+

Depot is written in C and there are many source files in + its distribution. Local modifications would be difficult to quickly + implement and test.

+
+
Stow +https://www.gnu.org/software/stow/
+
+

Stow is a stateless system. It requires no database or + configuration information.

+

Like Depot, it assumes that the package repository will be + stored under 'dir/stow/package' and the + target will be 'dir'. This can be overridden on the + command line and works well during the install phase.

+

Stow assumes "ownership" of the target area, + making it difficult to accommodate packages that are not under the + control of Stow. ("Ownership" in this case means that + Stow assumes ALL files in the target area will be under the + control of Stow. It does not imply that Stow modifies + Unix file permissions).

+

Because of Stow's assumed ownership it is + difficult for other packages not under the control of Stow to + be placed in the same target area. When deleting packages, Stow + examines everything in the target directory - whether it is associated + with the package it is trying to delete or not. This can be time + consuming and potentially dangerous as empty directories are also + removed - even empty directories that do not belong to the package + being removed.

+

Stow has a clever feature of folding and + unfolding directories. It attempts to optimise the number of + symbolic links by making links to directories if the directory is only + associated with a single package. If at a later date Stow + discovers another package that needs that directory it will unfold + that directory into a collection of symbolic links to files rather than + a single symbolic link to the directory. Stow will fold + the directory when removing packages if the remainder of the directory + is only concerned with a single package. While clever, this feature is + probably a waste of time and effort. It means that the entire package + target must be scanned to determine package ownership of links and as + packages will usually be replaced by newer versions a directory + fold will probably be short lived.

+

Stow will sometimes miss potential conflicts when run in + show only mode. The conflicts may occur when a directory is + unfolded and will not show up in show only mode.

+

Stow's author suggests that packages be compiled such that + they refer to files in the target location rather than the actual + package installation directory. This approach precludes the use of + multiple versions of packages with different configuration and/or + library files.

+

Stow is written in Perl and is only a few hundred + lines of code so local modifications can be accommodated. However there + are very few comments in the code which makes the process of + modification difficult.

+
+
+

Since the release of Graft 1.6, the existence of yet + another packaging program has been brought to the author's attention.

+
+
Encap +http://www.ks.uiuc.edu/Development/Computers/docs/sysadmin/Build/encap.html +
+
+

Encap grew out of work begun at the University of Illinois + Champaign-Urbana. It has the same underlying philosophy as Depot +, Stow and Graft - encapsulate packages into self + contained directories and use symbolic links to make them visible in a + common location.

+

Encap uses a combination of a csh wrapper and a + Perl program to accomplish its work. Like both Depot and + Stow, Encap assumes that all compiled packages will live + under a single directory hierarchy - by default 'dir +/encap/package'. It then attempts to create a symbolic + link tree for ALL the packages under this area. There doesn't appear to + be any easy way to support the quick addition or removal of a single + package.

+

A new release of Encap incorporating many new features was + expected to be available in early 1997, however no release greater than + version 1.2 has been forthcoming.

+

One good feature of Encap is the ability to exclude + specific files from the package tree. This concept has been + incorporated into Graft 1.7 and above.

+
+
+

Since the release of Graft 2.3, the existence of several + another packaging programs have been brought to the author's attention. + Rather than outline their features and whether or not the author feels + they are superior (or inferior) to Graft, a reference to each + package and a brief description is given and further research is left + as an exercise for the reader:

+
+
stowES
+
+
+https://os.inf.tu-dresden.de/~adam/stowES/
+
+

"stowES (stow Enhancement Script) is a Perl script which tries + to ease the use of the "stow" packaging program and software which can + be compiled and installed with autoconf. It automates the compilation + and installation of software packages and provides some useful + functions to maintain your stow packages (e.g., list packages, check + packages for integrity, etc.)."

+
+
opt_depot
+
+
+https://github.com/jonabbey/opt_depot
+
+

"opt_depot is a suite of Perl scripts which makes it easy to + manage installed software across a wide range of client systems. + opt_depot makes it possible to keep all files associated with a program + together in one directory, so installation and de-installation is + simple. opt_depot is easy to manage, and provides a scheme for + installing software in a truly portable fashion; packages may be + installed locally on client systems, or kept in a central package + archive for NFS access. "

+

This site also has links to several other package management + utilities, including Graft.

+
+
relink
+
+
+http://sourceforge.net/projects/relink/
+
+

"relink is a package management tool for organization and + management of software packages. It should run on any UNIX platform + that runs PERL. Similar tools include: rpm(REDHAT/Mandrake), + pkgadd(Slackware/SUN), stow(GNU) and depot(CMU)"

+
+
univSrcPkg
+
+
+http://freecode.com/articles/the-universal-source-package
+
+

Bud Bruegger has written a brief + paper outlining his thoughts on a "Universal Source Package" + solution.

+

This site also has links to other package management programs and + similar items of interest.

+
+
+
+

Design

+

This brings us to Graft. Graft has been designed + to use the best features of Depot, Stow and Encap + while maintaining as simple a mechanism as possible. The principles of + Graft are:

+ +

Control file precedence & conflict resolution +

+

As stated above, the various Graft control files have the + following precedence, from highest to lowest:

+
+    .nograft > .graft-exclude > .graft-include > .graft-config
+
+

The following table summarises the activities of Graft when + various control files are present:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Install
Target .nograft + .graft-exclude .graft-include + .graft-config
does not exist IGNORE IGNORE SYMLINK + COPY
symlink to source IGNORE IGNORE NOP + DELETE & COPY
symlink to other IGNORE IGNORE + CONFLICT N/A
symlink to other (crc match) N/A N/A + N/A NOP
symlink to other (crc diff) N/A N/A + N/A COPY.new
file IGNORE IGNORE CONFLICT + N/A
file (crc match) N/A N/A N/A + NOP
file (crc diff) N/A N/A N/A + COPY.new
not a file IGNORE IGNORE CONFLICT + CONFLICT
Delete
Target .nograft + .graft-exclude .graft-include + .graft-config
does not exist NOP NOP NOP + NOP
symlink to source DELETE DELETE + DELETE DELETE & DELETE.new
symlink to other CONFLICT CONFLICT + CONFLICT N/A
symlink to other (crc match) N/A N/A + N/A DELETE.new
symlink to other (crc diff) N/A N/A + N/A NOP
file NOTE NOTE CONFLICT N/A
file (crc match) N/A N/A N/A + DELETE.new
file (crc diff) N/A N/A N/A + NOP
not a file CONFLICT CONFLICT + CONFLICT CONFLICT
Prune
Target .nograft + .graft-exclude .graft-include + .graft-config
does not exist NOP NOP NOP + N/A
symlink to source NOP NOP NOP + N/A
symlink to other PRUNE PRUNE PRUNE + N/A
file PRUNE PRUNE PRUNE N/A
not a file PRUNE PRUNE PRUNE + N/A
+
+
+

History

+

Development on Graft began in October 1996. The initial + design used a configuration file to map the installed location of each + package to its target directory (that is the directory in which the + symbolic links would be created). Work proceeded at a regular pace and + by November 1997 Graft version 2.1 was released. In + this, and all subsequent versions, the configuration file had been + removed in favour of using default source and target directories.

+

No further work was performed until September 2000 when the concept + of bypassing or including files and directories using .nograft + or .graft-include files was introduced in Graft + version 2.3.

+

Again nothing changed until February 2002 when Rod Whitby identified + a bug in the handling of .graft-include files. Several other + users (Peter Bray, Robert Maldon and others) also reported some + deprecation warnings when using Graft with Perl + version 5.6.0. Graft version 2.4 was the end + of Graft development for over a decade.

+

In May 2015 Matias A. Fonzo contacted the author wishing to use + Graft in the Dragora GNU/Linux + distribution. Matias' usage of Graft lead to Graft + version 2.5 in June 2015 whereby the -P command line + option was silently ignored if the effective user was not root.

+

Since the release of Graft version 2.4 the + author's Perl code had improved somewhat so Graft + version 2.6 released in July 2015 represented a major clean up + of coding style and internals. No new behaviours or features were added + to the 2.6 release.

+

Matias made some more suggestions and improvements up to and + including Graft version 2.16 in April 2018. These + changes added the .graft-config control file, the -r + /rootdir option for specifying a new root directory, the -L + option for displaying default locations as well as introducing some + tighter controls on the messages and exit status of Graft + under various conditions.

+
+

Installation

+

Before installing Graft you'll need Perl 5.x +. Graft version 2.x requires features only available + with Perl 5.x and will not run with Perl 4. +x.

+

Your operating system and its file system(s) should also support + symbolic links. If you can't make symbolic links then you can't use + Graft! Graft will exit gracefully if your version of + Perl does not support symbolic links. It will also exit gracefully + if you attempt to graft a package into a file system that does + not support symbolic links - from a Linux ext4 file system + into an vfat file system for example.

+

Graft has been written to ensure it uses Perl + modules that are considered part of the core Perl + distribution. However it may be possible that you're using a home grown + installation of Perl or some distribution that doesn't have + the same Perl modules as the author's development environment.

+

If this is the case you'll see compile failures for the following + modules if they are unavailable:

+
+   File::Basename
+   Getopt::Long
+
+

You will not be able to install Graft until these modules + are available.

+

You may also see run-time failures when using Graft with +.graft-config files if the following modules are unavailable:

+
+   Compress::Raw::Zlib    (used in install and delete modes)
+   File::Copy             (only used in install mode)
+
+

If you don't have these modules and you do not intend to use +.graft-config files then you can continue to use Graft + without issue.

+

Follow these instructions to install Graft:

+
    +
  1. +

    Unpack the gzipped Graft distribution:

    +
    +    gunzip -c graft-2.16.tar.gz | tar xvf -
    +
    +
  2. +
  3. +

    change directories to the Graft distribution directory:

    +
    +    cd graft-2.16
    +
    +
  4. +
  5. +

    Create an writable version of the Makefile by running the + command

    +
    +    make -f Makefile.dist
    +
    +

    You'll see output similar to

    +
    +    cp Makefile.dist Makefile
    +    chmod 644 Makefile
    +
    +    ######################################################
    +    #                                                    #
    +    #       You'll now need to modify the Makefile       #
    +    #      variables to suit your local conditions.      #
    +    #                                                    #
    +    ######################################################
    +
    +    make: *** [Makefile] Error 1
    +
    +

    You can ignore the error message. That is just there to prevent the + creation of the graft executable before you've made your site + specific configurations to the Makefile.

    +
  6. +
  7. +

    Edit the Makefile. The following variables should be + modified to suit your local requirements:

    +
    +
    +
    +PACKAGEDIR     = /usr/local/pkgs
    +TARGETDIR      = /usr/local
    +
    +
    +
    +

    These two variables control your default package installation + and target directories. Most sites will probably choose to + install packages under a common installation directory and + then graft them into a common target directory.

    +

    If no specific target directory is given on the command + line, Graft will use the default value specified by + TARGETDIR. If a target directory is given on the + command line but is not fully qualified, the value specified by + TARGETDIR will be prepended to the command line argument.

    +

    Package names provided to Graft that are not fully + qualified will have the value specified by PACKAGEDIR + prepended to the command line arguments.

    +
    +
    +
    +TOP            = $(PACKAGEDIR)/graft-$(VERSION)
    +BIN            = $(TOP)/bin
    +MAN            = $(TOP)/man
    +DOC            = $(TOP)/doc
    +
    +
    +
    +

    There should be no need to modify these values unless you wish to + install Graft into a directory that is different from your + default package installation directory. If you do modify TOP + you should not change the values of BIN, MAN + and DOC. If you feel you must change these values then + perhaps you've misunderstood the concept behind Graft so a + re-read of this document may be in order.

    +
    +
    +
    +PERL           = /usr/bin/perl
    +
    +
    +
    +

    This variable refers to the location of the Perl 5.x + that will be used by the Graft executable. If you plan on + grafting Perl then this value should be the grafted + location of Perl rather than the installation location of + Perl. If you are using an operating system that comes with + Perl 5.x - such as RedHat or Ubuntu Linux - then you + don't need to worry about grafting Perl so the value + of PERL should reflect its installed location.

    +

    Most Unix, Linux and other Unix like operating systems ship with + Perl these days so modifying this value is probably unnecessary.

    +
    +
    +
    +BUILDPERL      = $(PERL)
    +
    +
    +
    +

    Perl is required during the make. You'll only need + to change this if the current installed location of Perl is + different to the future grafted location of Perl.

    +
    +
    +
    +LOGFILE                = /var/log/graft
    +
    +
    +
    +

    Graft logs all of its actions to a log file. Modify the + value of LOGFILE to suit your local needs. An + alternative name can be specified on the command line.

    +

    If you want logging disabled by default, set the value of + LOGFILE to /dev/null.

    +
    +
    +
    +GRAFT-IGNORE   = .nograft
    +GRAFT-EXCLUDE  = .graft-exclude
    +GRAFT-INCLUDE  = .graft-include
    +GRAFT-CONFIG   = .graft-config
    +
    +
    +
    +

    These variables hold the names of the special Graft files + that control whether or not subdirectories or files are grafted +. If you change these values, try to choose obvious names. If you want + the files to appear in a simple directory listing, do not use file + names that begin with a dot "." character.

    +
    +
    +
    +GRAFT-NEVER    =
    +
    +
    +
    +

    This variable holds the names of the files and/or directories that + should never be grafted. Typically these may be source code + repositories as used by systems such as CVS, or perhaps + lockfiles. The default value is empty but if you wish to specify + values, simply add them to the variable using only whitespace as a + separator. For example:

    +
    +GRAFT-NEVER     = CVS RCS SCCS .lock
    +
    +
    +
    +
    +NEVERGRAFT     = 0
    +
    +
    +
    +

    If this variable is set to 1, the files and/or + directories specified by GRAFT-NEVER will be + automatically excluded from the grafted directory.

    +

    If this variable is set to 0, the files and/or + directories specified by GRAFT-NEVER will be not be + excluded from the grafted directory.

    +

    The sense of this value is reversed by use of the -C + command line option.

    +

    The automatic exclusion is bypassed completely if the grafted + directory contains either a .nograft or .graft-include + file.

    +
    +
    +
    +PRUNED-SUFFIX  = .pruned
    +
    +
    +
    +

    This variable sets the suffix name of pruned files. + Pruned files will be renamed filename.pruned.

    +
    +
    +
    +CONFIG-SUFFIX  = .new
    +
    +
    +
    +

    This variable sets the suffix name of configuration files that will + be copied to the target directory when the target object is in conflict + with the package object. The files will be copied as filename +.new.

    +
    +
    +
    +SUPERUSER      = 1
    +
    +
    +
    +

    If this variable is set to 1 only the superuser can + install, delete or prune packages. This can be + overridden by the use of the -u command line option. + If this variable is set to 0, superuser privileges are + not required and the -u override command line option + is disabled.

    +

    If you are installing a private copy of Graft to manage + packages in your home directory you should set SUPERUSER + to 0.

    +

    If you're using Graft to manage a global set of packages + you should set SUPERUSER to 1.

    +
    +
    +
    +PRESERVEPERMS  = 0
    +
    +
    +
    +

    When grafting packages, Graft will create new + directories as required. By setting PRESERVEPERMS to + 1, the original user id, group id and file modes will be + carried over to the new directory. This variable is used only if + SUPERUSER is set to 1. The sense of this + variable can be reversed using the -P command line + option.

    +
    +
    +
    +DELETEOBJECTS  = 0
    +
    +
    +
    +

    When deleting grafted packages, Graft may leave + empty directories. Setting DELETEOBJECTS to 1 + will allow Graft to delete these directories. If + DELETEOBJECTS is 0 then Graft will + display an appropriate message reminding the user that a directory has + been emptied. The sense of this variable can be reversed using the + -D command line option.

    +

    It's probably not good practise to set this value to 1 + as some directories may be used as place holders by a number of + different packages. If the value is set to 0 deletion + of directories can be forced via the -D command line + option.

    +

    When pruning packages, graft can either remove conflicting + files or rename them. If DELETEOBJECTS is set to + 1 the default prune action will be to delete conflicting + objects. If DELETEOBJECTS is set to 0 + the default prune action will be to rename conflicting objects. The + sense of this variable can be reversed using the -D + command line option.

    +
    +
    +

    Save your changes and exit from the editor.

    +
  8. +
  9. +

    Remove any existing executables by running:

    +
    +    make clean
    +
    +

    You should see output similar to:

    +
    +    rm -f graft
    +
    +
  10. +
  11. +

    Create the Graft executable by running:

    +
    +    make
    +
    +

    You should see output similar to:

    +
    +    /usr/bin/perl -wc graft.pl
    +    graft.pl syntax OK
    +    sed                                         \
    +        -e 's#xCONFIG-SUFFIXx#.new#g'           \
    +        -e 's#xDELETEOBJECTSx#0#g'              \
    +        -e 's#xGRAFT-CONFIGx#.graft-config#g'   \
    +        -e 's#xGRAFT-EXCLUDEx#.graft-exclude#g' \
    +        -e 's#xGRAFT-IGNOREx#.nograft#g'        \
    +        -e 's#xGRAFT-INCLUDEx#.graft-include#g' \
    +        -e 's#xGRAFT-NEVERx##g'                 \
    +        -e 's#xLOGFILEx#/var/log/graft#g'       \
    +        -e 's#xNEVERGRAFTx#0#g'                 \
    +        -e 's#xPACKAGEDIRx#/usr/local/pkgs#g'   \
    +        -e 's#xPERLx#/usr/bin/perl#g'           \
    +        -e 's#xPRESERVEPERMSx#0#g'              \
    +        -e 's#xPRUNED-SUFFIXx#.pruned#g'        \
    +        -e 's#xSUPERUSERx#1#g'                  \
    +        -e 's#xTARGETDIRx#/usr/local#g'         \
    +        < graft.pl > graft
    +    chmod +x graft
    +    /usr/bin/perl -wc graft
    +    graft syntax OK
    +    if [ -n "" ];                                       \
    +    then                                                \
    +        AUTOIGNORE=1;                                   \
    +    else                                                \
    +        AUTOIGNORE=0;                                   \
    +    fi;                                                 \
    +    sed                                                 \
    +        -e "s#xAUTOIGNOREx#$AUTOIGNORE#g"               \
    +        -e 's#xCONFIG-SUFFIXx#.new#g'                   \
    +        -e 's#xDELETEOBJECTSx#0#g'                      \
    +        -e 's#xDOCx#/usr/local/pkgs/graft-2.16/doc#g'   \
    +        -e 's#xGRAFT-CONFIGx#.graft-config#g'           \
    +        -e 's#xGRAFT-EXCLUDEx#.graft-exclude#g'         \
    +        -e 's#xGRAFT-IGNOREx#.nograft#g'                \
    +        -e 's#xGRAFT-INCLUDEx#.graft-include#g'         \
    +        -e 's#xGRAFT-NEVERx##g'                         \
    +        -e 's#xLOGFILEx#/var/log/graft#g'               \
    +        -e 's#xNEVERGRAFTx#0#g'                         \
    +        -e 's#xPACKAGEDIRx#/usr/local/pkgs#g'           \
    +        -e 's#xPERLx#/usr/bin/perl#g'                   \
    +        -e 's#xPRESERVEPERMSx#0#g'                      \
    +        -e 's#xPRUNED-SUFFIXx#.pruned#g'                \
    +        -e 's#xSUPERUSERx#1#g'                          \
    +        -e 's#xTARGETDIRx#/usr/local#g'                 \
    +        -e 's#xVERSIONx#2.16#g'                         \
    +        < graft.man > graft.1
    +
    +
  12. +
  13. +

    If you're using the automounter under Solaris 2.x, + the installation process may not be able to directly create the + directory specified by TOP. If this is the case then + manually create this directory using whatever procedures are + appropriate for your operating system.

    +

    For example, if the /usr/local mount point is under the + control of the automounter via an entry in the auto_pkgs + map:

    +
    +    *   nfshost:/export/sparc-SunOS-5.5.1/usr/local/&
    +
    +

    you'll need to create the Graft installation directory by + executing the following command on the machine nfshost:

    +
    +    mkdir /export/sparc-SunOS-5.5.1/usr/local/pkgs/graft-2.16
    +
    +
  14. +
  15. +

    Install the Graft executable, manual page and documentation + by executing:

    +
    +    make install
    +
    +

    You should see output similar to:

    +
    +    mkdir -p /usr/local/pkgs/graft-2.16/bin
    +    cp graft /usr/local/pkgs/graft-2.16/bin
    +
    +    for i in graft.1;                                              \
    +    do                                                             \
    +        manpage=`basename $i`;                                     \
    +        man=`expr $i : '.*\.\(.\)'`;                               \
    +        mkdir -p /usr/local/pkgs/graft-2.16/man/man$man;           \
    +        cp $i /usr/local/pkgs/graft-2.16/man/man$man/$manpage;     \
    +        chmod 644 /usr/local/pkgs/graft-2.16/man/man$man/$manpage; \
    +    done
    +
    +    for i in graft.html graft.pdf graft.ps graft.txt;              \
    +    do                                                             \
    +        mkdir -p /usr/local/pkgs/graft-2.16/doc;                   \
    +        cp doc/$i /usr/local/pkgs/graft-2.16/doc;                  \
    +        chmod 644 /usr/local/pkgs/graft-2.16/doc/$i;               \
    +        touch /usr/local/pkgs/graft-2.16/doc/.nograft;             \
    +    done
    +
    +
  16. +
+

Graft is now installed and ready to be used.

+

NOTE: If you make changes to your Graft + installation at a later date, please run the following commands:

+
+    make clean
+    make install
+
+

Failure to do this may result in a Graft manual page that + does NOT reflect your current configuration.

+

Creating RPM and DEB packages

+

Beginning with Graft 2.11 there is now the ability to + create RPM and Debian installation packages. Obviously you'll need one + or more of the rpmbuild and dpkg-deb packages + installed on your system.

+

After editing the Makefile to suit your environment simply + run the appropriate make command to create the binary + installation package in the current directory:

+
+    make rpm
+
+

or

+
+    make deb
+
+

The creation of these packages is somewhat experimental. Please let + the author know if you have issues.

+
+

Grafting Graft and Perl - the + bootstrap problem

+

If you are using an operating system that comes with + Perl 5.x - such as RedHat or Ubuntu Linux - then you + don't need to worry about grafting Perl, so this + section can be ignored.

+

However if you are a creator of an operating system + distribution then this section may be relevant.

+

Embedded into the Graft executable is the location of the + Perl executable. If you've understood the concept behind Graft + then this location may be the grafted location of Perl + rather than the true location of Perl.

+

This presents a dilemma when you come to graft both + Graft and Perl. You can't run the grafted + location of the Graft executable because it doesn't exist yet, + and you can't run the real location of the Graft executable + because Perl hasn't been grafted yet.

+

Assuming that Graft and Perl are installed in

+
+    /usr/local/pkgs/graft-2.16
+    /usr/local/pkgs/perl-5.18.2
+
+

you can resolve this dilemma by executing the following commands:

+
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i graft-2.16
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i perl-5.18.2
+
+

This will graft both Graft and Perl from + the default package installation directory (as specified by + PACKAGEDIR in the Makefile) into your default target + directory (as specified by TARGETDIR in the +Makefile).

+

If you don't wish to use the default directories you can use the + following commands to graft the packages into /pkgs + instead of /usr/local for example:

+
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i -t /pkgs /usr/local/pkgs/graft-2.16
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i -t /pkgs /usr/local/pkgs/perl-5.18.2
+
+

Now both Graft and Perl have been grafted + and any other package can be grafted by executing the simpler + command:

+
+    graft -i package
+
+

The Graft distribution includes a program called +graftBootStrap.sh which allows you to easily graft both + Graft and Perl. It can be found in the contrib + directory of the distribution. Thanks to Gordon Rowell for providing + it.

+

You may also find the -L command line option to be useful + to programmatically determine where Graft expects to find + Perl along with the default locations of its log file, target and + package directories. See the Information section + below for details.

+
+

Using Graft

+

Compiling Packages

+

Any packages you wish to place under the control of Graft + should be compiled and installed in such a way that any package + dependent files are referenced with the ACTUAL package installation + directory rather than the common area in which Graft will be + creating symbolic links. For example, ensure that Perl version + 5.18.2 is looking for its library files in +/usr/local/pkgs/perl-5.18.2/lib/perl5 instead of +/usr/local/lib/perl5. This approach will allow you to easily + separate multiple versions of the same package without any problems.

+
+

Graft command line options

+

All of the details concerning actions, package locations and target + directories are passed to Graft on the command line. ( +Graft 1.x used a configuration file. This has now been + deprecated in favour of a log file).

+

Graft's command line options can be summarised as:

+
+    graft -i [-P|u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -d [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -p [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -L
+
+

Graft has four basic actions:

+
    +
  1. +

    Install

    +
    +    graft -i [-C] [-P|u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    +
    +
    -i
    +
    +

    Install symbolic links from the package installation directory to + the target directory. Requires superuser privileges if + SUPERUSER was set to 1 in the Makefile +.

    +
    +
    -C
    +
    +

    If NEVERGRAFT was set to 1 in the +Makefile, disable the automatic exclusion of files and/or + directories whose names exactly match the values specified by + GRAFT-NEVER in the Makefile.

    +

    If NEVERGRAFT was set to 0 in the +Makefile, force the automatic exclusion of files and/or directories + whose names exactly match the values specified by GRAFT-NEVER + in the Makefile.

    +

    Can only be used with the -i option.

    +

    This option is ignored for each grafted directory, if the + directory contains a .nograft or .graft-include file.

    +

    The Graft manual page will correctly reflect the behaviour + of this option based on the values specified in the Makefile. + If there are no objects specified for GRAFT-NEVER then + this option will be silently ignored and will not appear in the help + message nor in the manual page.

    +
    +
    -P
    +
    +

    Preserve modes and ownerships when creating new directories or + copying files if PRESERVEPERMS was set to 0 + in the Makefile. Do not preserve modes and ownerships if the + option is not provided on the command line.

    +

    Do not preserve modes and ownerships when creating new directories + or copying files if PRESERVEPERMS was set to 1 + in the Makefile. Preserve modes and ownerships if the option + is not provided on the command line.

    +

    Cannot be used with the -u option.

    +

    This option will be silently ignored if the effective user of + Graft is not root.

    +

    The Graft manual page will correctly reflect the behaviour + of this option based on the values specified in the Makefile. + This option will be silently ignored and will not appear in the help + message nor in the manual page if SUPERUSER was set to + 0 in the Makefile.

    +
    +
    -u
    +
    +

    Superuser privileges are not required when installing packages.

    +

    Cannot be used with the -P option.

    +

    This option is only available if SUPERUSER was set + to 1 in the Makefile.

    +

    The Graft manual page will correctly reflect the behaviour + of this option based on the values specified in the Makefile. + This option will be silently ignored and will not appear in the help + message nor in the manual page if SUPERUSER was set to + 0 in the Makefile.

    +
    +
    -l log
    +
    +

    Specify an alternate log file instead of the default specified by + LOGFILE in the Makefile. No logging is performed if + the -n option is used.

    +

    Log entries have the form:

    +
    +    878790215   1.10+   I    /usr/local/pkgs/cpio-2.4.2            /usr/local
    +    878888916   2.1     I    /usr/local/pkgs/gzip-1.2.4            /usr/local
    +    878888916   2.1     IC   /usr/local/pkgs/gzip-1.2.4/bin/gzip   invalid symlink
    +
    +

    This shows that a development version of graft (1.10+) was + used to install symbolic links from /usr/local/pkgs/cpio-2.4.2 + to /usr/local. A new version of graft (2.1) was used + to install symbolic links from /usr/local/pkgs/gzip-1.2.4 to +/usr/local. The IC entry indicates that a conflict + occurred during this installation - the file +/usr/local/pkgs/bin/gzip was a symbolic link to something other + than /usr/local/pkgs/gzip-1.2.4/bin/gzip.

    +
    +
    -n
    +
    +

    List actions but do not perform them. Implies the very verbose + option. Does not require superuser privileges regardless of the value + of SUPERUSER in the Makefile.

    +
    +
    -v
    +
    +

    Be verbose.

    +
    +
    -V
    +
    +

    Be very verbose.

    +
    +
    -r /rootdir
    +
    +

    Use the fully qualified named directory as the root directory for + all graft operations. The source directory, target directory and log + file will all be relative to this specific directory.

    +

    Can only be used by the superuser.

    +
    +
    -s
    +
    +

    Stow/Depot compatibility mode. Infer the Graft + target directory from each package installation directory in the manner + of Stow and Depot.

    +

    Target directory is the dirname of the dirname of + the package installation directory. (Yes that really is two dirname +s). So if the package installation directory is

    +
    +    /usr/local/depot/gzip-1.2.4
    +
    +

    the package will be grafted into

    +
    +    /usr/local
    +
    +

    Cannot be used with the -t option.

    +
    +
    -t target
    +
    +

    Override the default graft target directory with + target. The value of target + must be a fully qualified directory and it must exist.

    +

    Cannot be used with the -s option.

    +
    +
    package
    +
    +

    Install the named package. If package is a fully + qualified directory, use it as the package installation directory. If + package is not a fully qualified directory, prepend it with + the value of PACKAGEDIR as specified in the +Makefile.

    +
    +
    +
  2. +
  3. +

    Delete

    +
    +    graft -d [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    +
    +
    -d
    +
    +

    Delete symbolic links from the package target directory to the + package installation directory. Requires superuser privileges if + SUPERUSER was set to 1 in the Makefile +.

    +
    +
    -D
    +
    +

    Delete empty directories if DELETEOBJECTS was set + to 0 in the Makefile. If the option is not + provided on the command line, notify the user that a directory has been + emptied.

    +

    Do not delete empty directories if DELETEOBJECTS + was set to 1 in the Makefile. Notify the user + that a directory has been emptied. If the option is not provided on the + command line, delete empty directories.

    +

    The Graft manual page will correctly reflect the behaviour + of this option based on the values specified in the Makefile.

    +
    +
    -u
    +
    +

    Superuser privileges are not required when deleting packages.

    +

    This option is only available if SUPERUSER was set + to 1 in the Makefile.

    +

    The Graft manual page will correctly reflect the behaviour + of this option based on the values specified in the Makefile. + This option will be silently ignored and will not appear in the help + message nor in the manual page if SUPERUSER was set to + 0 in the Makefile.

    +
    +
    -l log
    +
    +

    Specify an alternate log file instead of the default specified by + LOGFILE in the Makefile. No logging is performed if + the -n option is used.

    +

    Log entries have the form:

    +
    +    879126278       1.10+   D       /usr/local/pkgs/weblint-1.017     /usr/local
    +    879126278       1.10+   DC      /usr/local/pkgs/weblint-1.017/bin/weblint  file exists
    +    879126278       1.10+   DC      /usr/local/pkgs/weblint-1.017/man/man1/weblint.1  file exists
    +
    +

    This shows that a development version of graft (1.10+) was + used to delete symbolic links from /usr/local to +/usr/local/pkgs/weblint-1.017. The DC entries indicate + that conflicts occurred during this action - the files +/usr/local/bin/weblint and /usr/local/man/man1/weblint.1 + already exist.

    +
    +
    -n
    +
    +

    List actions but do not perform them. Implies the very verbose + option. Does not require superuser privileges regardless of the value + of SUPERUSER in the Makefile.

    +
    +
    -v
    +
    +

    Be verbose.

    +
    +
    -V
    +
    +

    Be very verbose.

    +
    +
    -r /rootdir
    +
    +

    Use the fully qualified named directory as the root directory for + all graft operations. The source directory, target directory and log + file will all be relative to this specific directory.

    +

    Can only be used by the superuser.

    +
    +
    -s
    +
    +

    Stow/Depot compatibility mode. Infer the Graft + target directory from each package installation directory in the manner + of Stow and Depot.

    +

    Target directory is the dirname of the dirname of + the package installation directory. (Yes that really is two dirname +s). So if the package installation directory is

    +
    +    /usr/local/depot/gzip-1.2.4
    +
    +

    the package will be grafted into

    +
    +    /usr/local
    +
    +

    Cannot be used with the -t option.

    +
    +
    -t target
    +
    +

    Override the default graft target directory with + target. The value of target + must be a fully qualified directory and it must exist.

    +

    Cannot be used with the -s option.

    +
    +
    package
    +
    +

    Delete the named package. If package is a fully + qualified directory, use it as the package installation directory. If + package is not a fully qualified directory, prepend it with + the value of PACKAGEDIR as specified in the +Makefile.

    +
    +
    +
  4. +
  5. +

    Prune

    +
    +    graft -p [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    +
    +
    -p
    +
    +

    Prune objects (files, links or directories) from the package target + directory that are in conflict with the package installation directory. + Requires superuser privileges if SUPERUSER was set to + 1 in the Makefile.

    +
    +
    -D
    +
    +

    Remove conflicting objects if DELETEOBJECTS was set + to 0 in the Makefile. Rename conflicting + objects as object.pruned if the option is not + provided on the command line.

    +

    Rename conflicting objects to object.pruned if + DELETEOBJECTS was set to 1 in the +Makefile. Remove conflicting objects if the option is not provided + in the command line.

    +

    If a directory is to be removed and it is not empty, it will be + renamed as dir.pruned and a suitable warning message + will be given regardless of the sense of this flag.

    +

    The Graft manual page will correctly reflect the behaviour + of this option based on the values specified in the Makefile.

    +
    +
    -u
    +
    +

    Superuser privileges are not required when pruning packages.

    +

    This option is only available if SUPERUSER was set + to 1 in the Makefile.

    +

    The Graft manual page will correctly reflect the behaviour + of this option based on the values specified in the Makefile. + This option will be silently ignored and will not appear in the help + message nor in the manual page if SUPERUSER was set to + 0 in the Makefile.

    +
    +
    -l log
    +
    +

    Specify an alternate log file instead of the default specified by + LOGFILE in the Makefile. No logging is performed if + the -n option is used.

    +

    Log entries have the form:

    +
    +    879126283       1.10+   P       /usr/local/pkgs/weblint-1.017     /usr/local
    +
    +

    This shows that a development version of graft (1.10+) was + used to delete objects from /usr/local that were in conflict + with /usr/local/pkgs/weblint-1.017.

    +
    +
    -n
    +
    +

    List actions but do not perform them. Implies the very verbose + option. Does not require superuser privileges regardless of the value + of SUPERUSER in the Makefile.

    +
    +
    -v
    +
    +

    Be verbose.

    +
    +
    -V
    +
    +

    Be very verbose.

    +
    +
    -r /rootdir
    +
    +

    Use the fully qualified named directory as the root directory for + all graft operations. The source directory, target directory and log + file will all be relative to this specific directory.

    +

    Can only be used by the superuser.

    +
    +
    -s
    +
    +

    Stow/Depot compatibility mode. Infer the Graft + target directory from each package installation directory in the manner + of Stow and Depot.

    +

    Target directory is the dirname of the dirname of + the package installation directory. (Yes that really is two dirname +s). So if the package installation directory is

    +
    +    /usr/local/depot/gzip-1.2.4
    +
    +

    the package will be grafted into

    +
    +    /usr/local
    +
    +

    Cannot be used with the -t option.

    +
    +
    -t target
    +
    +

    Override the default graft target directory with + target. The value of target + must be a fully qualified directory and it must exist.

    +

    Cannot be used with the -s option.

    +
    +
    package
    +
    +

    Prune the named package. If package is a fully + qualified directory, use it as the package installation directory. If + package is not a fully qualified directory, prepend it with + the value of PACKAGEDIR as specified in the +Makefile.

    +
    +
    +
  6. +
  7. +

    Information

    +
    +    graft -L
    +
    +
    +
    -L
    +
    +

    This is a special mode and it overrides all other command line + arguments. When present graft will display the + default locations for Perl, the graft log file, the target + directory, and the package directory in a form suitable for creating + environment variables for Bourne like shells. The output will appear on + STDOUT as follows:

    +
    +    GRAFT_PERL=/usr/bin/perl
    +    GRAFT_LOGFILE=/var/log/graft
    +    GRAFT_TARGETDIR=/usr/local
    +    GRAFT_PACKAGEDIR=/usr/local/pkgs
    +
    +

    You can set these environment variables using one of the following + methods.

    +
    +    eval "$(graft -L)"    # modern shells such as bash, zsh etc
    +    eval "`graft -L`"     # older shells such as sh etc
    +
    +
    +
    +
  8. +
+
+

Testing the Graft Installation

+

Before creating the symbolic links from the target directory to the + package directory, you may wish to see what actions Graft will + perform. Execute the following command:

+
+    graft -i -n package-name
+
+

The -i option tells Graft to install the package + and the -n option tells Graft to report on its + actions without actually performing them. The default Graft + target directory will be used and the package installation directory + will be taken from the fully qualified package argument or the default + value will be prepended to the package argument if it is not fully + qualified.

+

Graft will report on the following actions:

+ +

If you were to test the installation of the kermit-5A190 + package you would execute the command:

+
+    graft -i -n kermit-5A190
+
+ You should see output resembling: +
+    Installing   links to /usr/local/pkgs/kermit-5A190 in /usr/local
+    Processing   /usr/local/pkgs/kermit-5A190
+    SYMLINK      /usr/local/README -> /usr/local/pkgs/kermit-5A190/README
+    NOP          /usr/local/pkgs/kermit-5A190/bin and /usr/local/bin are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    SYMLINK      /usr/local/bin/kermit -> /usr/local/pkgs/kermit-5A190/bin/kermit
+    SYMLINK      /usr/local/bin/wart -> /usr/local/pkgs/kermit-5A190/bin/wart
+    NOP          /usr/local/pkgs/kermit-5A190/man and /usr/local/man are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    NOP          /usr/local/pkgs/kermit-5A190/man/man1 and /usr/local/man/man1 are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    SYMLINK      /usr/local/man/man1/kermit.1 -> /usr/local/pkgs/kermit-5A190/man/man1/kermit.1
+    MKDIR        /usr/local/doc
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    SYMLINK      /usr/local/doc/ckccfg.doc -> /usr/local/pkgs/kermit-5A190/doc/ckccfg.doc
+    SYMLINK      /usr/local/doc/ckuins.doc -> /usr/local/pkgs/kermit-5A190/doc/ckuins.doc
+    SYMLINK      /usr/local/doc/ckc190.upd -> /usr/local/pkgs/kermit-5A190/doc/ckc190.upd
+    SYMLINK      /usr/local/doc/ckcker.upd -> /usr/local/pkgs/kermit-5A190/doc/ckcker.upd
+    SYMLINK      /usr/local/doc/ckaaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckaaaa.hlp
+    SYMLINK      /usr/local/doc/ckuaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckuaaa.hlp
+    NOP          /usr/local/pkgs/kermit-5A190/lib and /usr/local/lib are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    SYMLINK      /usr/local/lib/ckedemo.ini -> /usr/local/pkgs/kermit-5A190/lib/ckedemo.ini
+    SYMLINK      /usr/local/lib/ckeracu.ini -> /usr/local/pkgs/kermit-5A190/lib/ckeracu.ini
+    SYMLINK      /usr/local/lib/ckermit.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermit.ini
+    SYMLINK      /usr/local/lib/ckermod.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermod.ini
+    SYMLINK      /usr/local/lib/cketest.ini -> /usr/local/pkgs/kermit-5A190/lib/cketest.ini
+    SYMLINK      /usr/local/lib/ckevt.ini -> /usr/local/pkgs/kermit-5A190/lib/ckevt.ini
+    SYMLINK      /usr/local/lib/ckurzsz.ini -> /usr/local/pkgs/kermit-5A190/lib/ckurzsz.ini
+
+

This output shows you that most of the directories already exist + (indicated by the NOP flags). A symbolic link will be created + in the relevant target directory to each of the files in the + kermit-5A190 package. One directory exists in the kermit-5A190 + package that does not exist in the target - doc. This + directory will be created by Graft.

+

NOTE: If you are using the automounter you + may not be able to create the directory /usr/local/doc. You'll + have to create the directory on the NFS server under the file system in + which it really lives. You should be familiar with the peculiarities of + the automounter and your specific site configuration before + creating any directories directly under mount points used by the + automounter.

+
+

Installing Packages

+

Once you have ensured that Graft will perform the correct + actions, you can execute:

+
+    graft -i package-name
+
+

So to install kermit you would execute:

+
+    graft -i kermit-5A190
+
+

There will be no output from Graft unless it encounters a + conflict. If you wish to see more information you can specify one of + the verbose flags. For a minimum of output you can execute:

+
+    graft -i -v kermit-5A190
+
+

You should see the following output:

+
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+
+

If you choose the very verbose option by executing:

+
+    graft -i -V kermit-5A190
+
+

the output will be the same as that when the -n option was + used, however this time Graft will actually create the + symbolic links.

+
+    Installing   links to /usr/local/pkgs/kermit-5A190 in /usr/local
+    Processing   /usr/local/pkgs/kermit-5A190
+    SYMLINK      /usr/local/README -> /usr/local/pkgs/kermit-5A190/README
+    NOP          /usr/local/pkgs/kermit-5A190/bin and /usr/local/bin are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    SYMLINK      /usr/local/bin/kermit -> /usr/local/pkgs/kermit-5A190/bin/kermit
+    SYMLINK      /usr/local/bin/wart -> /usr/local/pkgs/kermit-5A190/bin/wart
+    NOP          /usr/local/pkgs/kermit-5A190/man and /usr/local/man are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    NOP          /usr/local/pkgs/kermit-5A190/man/man1 and /usr/local/man/man1 are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    SYMLINK      /usr/local/man/man1/kermit.1 -> /usr/local/pkgs/kermit-5A190/man/man1/kermit.1
+    NOP          /usr/local/pkgs/kermit-5A190/doc and /usr/local/doc are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    SYMLINK      /usr/local/doc/ckccfg.doc -> /usr/local/pkgs/kermit-5A190/doc/ckccfg.doc
+    SYMLINK      /usr/local/doc/ckuins.doc -> /usr/local/pkgs/kermit-5A190/doc/ckuins.doc
+    SYMLINK      /usr/local/doc/ckc190.upd -> /usr/local/pkgs/kermit-5A190/doc/ckc190.upd
+    SYMLINK      /usr/local/doc/ckcker.upd -> /usr/local/pkgs/kermit-5A190/doc/ckcker.upd
+    SYMLINK      /usr/local/doc/ckaaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckaaaa.hlp
+    SYMLINK      /usr/local/doc/ckuaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckuaaa.hlp
+    NOP          /usr/local/pkgs/kermit-5A190/lib and /usr/local/lib are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    SYMLINK      /usr/local/lib/ckedemo.ini -> /usr/local/pkgs/kermit-5A190/lib/ckedemo.ini
+    SYMLINK      /usr/local/lib/ckeracu.ini -> /usr/local/pkgs/kermit-5A190/lib/ckeracu.ini
+    SYMLINK      /usr/local/lib/ckermit.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermit.ini
+    SYMLINK      /usr/local/lib/ckermod.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermod.ini
+    SYMLINK      /usr/local/lib/cketest.ini -> /usr/local/pkgs/kermit-5A190/lib/cketest.ini
+    SYMLINK      /usr/local/lib/ckevt.ini -> /usr/local/pkgs/kermit-5A190/lib/ckevt.ini
+    SYMLINK      /usr/local/lib/ckurzsz.ini -> /usr/local/pkgs/kermit-5A190/lib/ckurzsz.ini
+
+

NOTE: In this case the /usr/local/doc + directory was not created by Graft because /usr/local + is a mount point controlled by the automounter. The doc + directory was created manually prior to executing Graft.

+
+

Bypassing package directories

+

You may have the need to place only part of a package under the + control of Graft. Examples of such occasions may be:

+ +

You can force Graft to bypass a directory by creating the + file

+
+    package-name/dir/dir/.nograft
+
+

Using the second example above, if you were to create the file:

+
+    /usr/local/pkgs/perl-5.18.2/lib/perl5/.nograft
+
+

Graft would create directories and symbolic links for every + file and directory down to /usr/local/pkgs/perl-5.18.2/lib. + The perl5 directory and anything below it would not be + created.

+
+

Including specific files and/or directories

+

There may be the occasional need to include specific files and/or + directories in a directory, rather than the entire directory tree + itself. An example of such an occurrence would be the case where a + package contains a number of subdirectories, only one of which is + required to be grafted.

+

You can force Graft to only include any number of files + and/or directories in a package directory by creating the file

+
+    .graft-include
+
+

in the same directory.

+

.graft-include will contain a list of file and/or directory + names - one per line - of the files and/or directories you wish to + include.

+

Consider the a2ps package for example. When installed it + contains the following directories:

+
+    /usr/local/pkgs/a2ps-4.13b/bin
+    /usr/local/pkgs/a2ps-4.13b/etc
+    /usr/local/pkgs/a2ps-4.13b/include
+    /usr/local/pkgs/a2ps-4.13b/info
+    /usr/local/pkgs/a2ps-4.13b/lib
+    /usr/local/pkgs/a2ps-4.13b/man
+    /usr/local/pkgs/a2ps-4.13b/share
+
+

The only directory you wish to graft is the bin + directory. You could place a .nograft file in each of the + other directories, OR you could create a single +.graft-include file in +/usr/local/pkgs/a2ps-4.13b/.graft-include. This file would contain

+
+    bin
+
+

Now only the bin directory will be grafted.

+
+

Excluding specific files and/or directories

+

There may be the occasional need to exclude specific files and/or + directories from a directory, rather than the entire directory itself. + An example of such an occurrence would be the case where files from + different packages have the same name. Emacs and Xemacs + use the same names for a number of their configuration files for + example.

+

You can force Graft to exclude any number of files and/or + directories from a package directory by creating the file

+
+    .graft-exclude
+
+

in the same directory.

+

.graft-exclude will contain a list of file and/or directory + names - one per line - of the files and/or directories you wish to + exclude.

+

For example, if you did not wish the file

+
+    /usr/local/pkgs/sudo-1.5.3/etc/sudoers
+
+

to be grafted as

+
+    /usr/local/etc/sudoers
+
+

but you did want

+
+    /usr/local/pkgs/sudo-1.5.3/etc/visudo
+
+

to be grafted as

+
+    /usr/local/etc/visudo
+
+

you would create the file

+
+    /usr/local/pkgs/sudo-1.5.3/etc/.graft-exclude
+
+

and ensure its contents contained the line:

+
+    sudoers
+
+

NOTE: Any entries made in a .graft-exclude + file will override the same entries made in a .graft-include + file. That is, if a file or directory name is listen in both a +.graft-exclude and a .graft-include file, it will be + excluded from the graft.

+
+

Grafting configuration files

+

Beginning with Graft 2.11 there is now the ability to treat + a package directory as a repository for configuration files. In this + case you would place a .graft-config file in the package + directory and any files in that directory would be copied + to the target directory. Files in conflict would also be copied but + would have a default suffix of .new to ensure the existing + file is not clobbered. Conflict discovery is achieved using a simple + 32-bit CRC check. This feature has been added to assist operating + system distributors manage system configuration files, specifically it + was added at the request of the maintainer of the +Dragora GNU/Linux distribution.

+

Consider the following example. You may wish to upgrade the + openssh server as part of an upgrade to your distribution. In + order to preserve any local user modifications to the relevant + configuration files you would add a .graft-config file to the + package as follows:

+
+    /usr/local/pkgs/openssh-server-6.61/etc/default/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/init.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/init/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/network/if-up.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/pam.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/ufw/applications.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/lib/systemd/system/.graft-config
+
+

The other directories in the distribution would not require any + control files.

+

Imagine that the local administrator has made some changes to +/etc/pam.d/sshd such as adding additional authentication methods to + support two-factor authentication for example. As the distribution + maintainer you do not want to reverse this local change so when the + local administrator upgrades the distribution, Graft + copies the new /etc/pam.d/sshd file to +/etc/pam.d/sshd.new which allows the local administrator to merge + their changes with any new features supported by the upgrade.

+

To take full advantage of this feature you may need to explicitly + set the target directory as follows:

+
+    graft -i -t / openssh-server-6.61
+
+
+

Grafting part of a package

+

Some packages can be successfully used when only part of their + installation directory is grafted. Other packages are + recalcitrant and need some special hand holding which can only be + solved by grafting each section of the package separately.

+

The first scenario can be handled by either .nograft files + or partial grafts. Consider Perl version 5.18.2 +. When installed in its own directory

+
+    /usr/local/pkgs/perl-5.18.2
+
+

there are three subdirectories

+
+    drwxr-sr-x   2 psamuel  bisg         512 Oct 30  1996 bin
+    drwxr-sr-x   3 psamuel  bisg         512 Oct 30  1996 lib
+    drwxr-sr-x   4 psamuel  bisg         512 Oct 30  1996 man
+
+

Everything in the lib directory is exclusive to Perl + and does not require grafting. Therefore, perl-5.18.2 + can be grafted using either of the following two methods:

+
+    touch /usr/local/pkgs/perl-5.18.2/lib/.nograft
+    graft -i perl-5.18.2
+
+ or +
+    graft -it /usr/local/bin perl-5.18.2/bin
+    graft -it /usr/local/man perl-5.18.2/man
+
+

Now let's consider a recalcitrant package - ObjectStore + version 4.0.2.a.0. When installed in

+
+    /usr/local/pkgs/ostore-4.0.2.a.0
+
+

the following files and directories are available:

+
+    -rwxrwxr-x   1 pauln    one3        1089 Oct 31  1996 Copyright
+    drwxrwxrwx   8 pauln    one3         512 Oct  2  1996 common
+    drwxrwxrwx   6 pauln    one3         512 Oct 31  1996 sunpro
+    -rw-r-----   1 root     one3     1900544 Apr 29  1997 txn.log
+
+

The executable programs that need to be grafted are in +sunpro/bin and the manual pages that need to be grafted + are in common/man. Everything else in the package does not + need to be grafted. If the entire package was to be + grafted the result would be two directories that are not in the + regular $PATH and $MANPATH + environment variables - namely /usr/local/common/man and +/usr/local/sunpro/bin, plus a host of other directories that are + not relevant for grafting. No amount of .nograft and +.graft-exclude juggling will solve this problem.

+

The solution is to use two partial grafts:

+
+    graft -it /usr/local/bin ostore-4.0.2.a.0/sunpro/bin
+    graft -it /usr/local/man ostore-4.0.2.a.0/common/bin
+
+

Using this approach, the correct executables and manual pages are + available without the need to graft unnecessary files and + directories.

+
+

Deleting and/or Upgrading Packages

+

If you wish to upgrade a package - let's assume you wish to upgrade + kermit from version 5A190 to version 6.0.192 - you'd follow these + steps.

+

Firstly, you'd compile and install kermit-6.0.192 in

+
+    /usr/local/pkgs/kermit-6.0.192
+
+

Once you'd tested it to your satisfaction, you'd need to delete the + symbolic links to the current grafted version. You can check + which actions Graft will perform by executing:

+
+    graft -d -n kermit-5A190
+
+

You'll see output similar to

+
+    Uninstalling links from /usr/local to /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    UNLINK       /usr/local/bin/kermit
+    UNLINK       /usr/local/bin/wart
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    UNLINK       /usr/local/man/man1/kermit.1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    UNLINK       /usr/local/doc/ckccfg.doc
+    UNLINK       /usr/local/doc/ckuins.doc
+    UNLINK       /usr/local/doc/ckc190.upd
+    UNLINK       /usr/local/doc/ckcker.upd
+    UNLINK       /usr/local/doc/ckaaaa.hlp
+    UNLINK       /usr/local/doc/ckuaaa.hlp
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    UNLINK       /usr/local/lib/ckedemo.ini
+    UNLINK       /usr/local/lib/ckeracu.ini
+    UNLINK       /usr/local/lib/ckermit.ini
+    UNLINK       /usr/local/lib/ckermod.ini
+    UNLINK       /usr/local/lib/cketest.ini
+    UNLINK       /usr/local/lib/ckevt.ini
+    UNLINK       /usr/local/lib/ckurzsz.ini
+    UNLINK       /usr/local/lib/.testing
+
+

If you're happy with the output from the test deletion you can + delete the grafted package. Once again, you'll only see output + if a failure occurs unless you use one of the verbose options.

+

If you execute:

+
+    graft -dV kermit-5A190
+
+

you'll see:

+
+    Uninstalling links from /usr/local to /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    UNLINK       /usr/local/bin/kermit
+    UNLINK       /usr/local/bin/wart
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    UNLINK       /usr/local/man/man1/kermit.1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    UNLINK       /usr/local/doc/ckccfg.doc
+    UNLINK       /usr/local/doc/ckuins.doc
+    UNLINK       /usr/local/doc/ckc190.upd
+    UNLINK       /usr/local/doc/ckcker.upd
+    UNLINK       /usr/local/doc/ckaaaa.hlp
+    UNLINK       /usr/local/doc/ckuaaa.hlp
+    EMPTY        /usr/local/doc is now empty. Delete manually if necessary.
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    UNLINK       /usr/local/lib/ckedemo.ini
+    UNLINK       /usr/local/lib/ckeracu.ini
+    UNLINK       /usr/local/lib/ckermit.ini
+    UNLINK       /usr/local/lib/ckermod.ini
+    UNLINK       /usr/local/lib/cketest.ini
+    UNLINK       /usr/local/lib/ckevt.ini
+    UNLINK       /usr/local/lib/ckurzsz.ini
+
+

NOTE: In this case the existence of an empty + directory has been discovered. If Graft empties a directory + during a package deletion, it will either notify you or delete the + directory depending on the combination of variables in the Makefile + and command line options. It's probably better practise not to + automatically delete empty directories as they may be used by other + packages - such as lock file directories for example.

+

Now you can remove the real package contents. (You may not + wish to do this immediately as some legacy systems may depend on + features provided by the older version or you may feel the need for + further testing before feeling confident that the old version can be + removed):

+
+    rm -rf /usr/local/pkgs/kermit-5A190
+
+

Now you can graft the new version of kermit. + Execute:

+
+    graft -i -n kermit-6.0.192
+
+

to ensure that the grafting will proceed without error. + Once you are satisfied that this is the case you can graft the + new package by executing:

+
+    graft -i kermit-6.0.192
+
+
+

Transitioning a package to Graft + control

+

Graft can be used to easily transition a package from its + current installation in your target directory to a grafted + installation.

+

As an example, let's consider the package weblint version + 1.017. It consists of three files installed in:

+
+    /usr/local/bin/weblint
+    /usr/local/lib/global.weblintrc
+    /usr/local/man/man1/weblint.1
+
+

The first step is to create a new copy of the package in its own + directory:

+
+    /usr/local/pkgs/weblint-1.017
+
+

Ensure that any references to library files are now made to +/usr/local/pkgs/weblint-1.017/lib instead of /usr/local/lib +.

+

Test the new installation to ensure it behaves as expected.

+

Then prune the old files from /usr/local/* using:

+
+    graft -pV weblint-1.017
+
+

You'd expect to see output similar to:

+
+    Pruning      files in /usr/local which conflict with /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017/man
+    Processing   /usr/local/pkgs/weblint-1.017/man/man1
+    RENAME       /usr/local/man/man1/weblint.1
+    Processing   /usr/local/pkgs/weblint-1.017/bin
+    RENAME       /usr/local/bin/weblint
+    Processing   /usr/local/pkgs/weblint-1.017/lib
+    RENAME       /usr/local/lib/global.weblintrc
+
+

If you elected to delete conflicting files instead of renaming them + you'd use:

+
+    graft -pDV weblint-1.017
+
+

and you'd see output similar to:

+
+    Pruning      files in /usr/local which conflict with /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017/man
+    Processing   /usr/local/pkgs/weblint-1.017/man/man1
+    UNLINK       /usr/local/man/man1/weblint.1
+    Processing   /usr/local/pkgs/weblint-1.017/bin
+    UNLINK       /usr/local/bin/weblint
+    Processing   /usr/local/pkgs/weblint-1.017/lib
+    UNLINK       /usr/local/lib/global.weblintrc
+
+

Now the new version of weblint 1.017 can be grafted + in place:

+
+    graft -i weblint-1.017
+
+

The grafted version of weblint can now be tested.

+

If we renamed conflicting files, they can be removed once the + grafted weblint has been satisfactorily tested:

+
+    rm /usr/local/man/man1/weblint.1.pruned
+    rm /usr/local/bin/weblint.pruned
+    rm /usr/local/lib/global.weblintrc.pruned
+
+
+

Conflict Processing

+

Occasionally Graft will fail to completely install a + package. This occurs because Graft encounters a conflict. A + conflict is defined as one of the following possibilities:

+
+ + + + + + +
Package Object Target Object
directory not a directory
file directory
file file
file symbolic link to something other than the package + object
+
+

If Graft encounters such a conflict during the installation + of a package it will report the conflict and exit.

+

Resolving the conflict depends on the nature of the conflict and is + beyond the scope of this discussion - however most conflicts will + either be the result of attempting to graft a package on top + of the same package actually installed in the target directory or a + file name clash between two (or more) different packages.

+

Conflicts arising from the pre-existence of a package in the target + directory can be resolved using graft's prune mechanism + described above in "Transitioning a package to + Graft control".

+

File name clash conflicts can be resolved by the use of either a +.nograft or .graft-exclude + file or by grafting only part of a package as described above + in "Grafting part of a package".

+

If Graft encounters a conflict while deleting a package, it + will report the conflict and continue deleting the remainder of the + package. In this way Graft will delete as much of the package + as possible. Conflicts that arise during deletion will probably be the + result of an incorrectly installed package or the installation of other + components of the same package without the use of Graft.

+

Conflict messages are written to standard error. All other messages + are written to standard output. To quickly determine if a package will + have any conflicts when grafted, redirect standard output to +/dev/null

+
+    graft -i -n package > /dev/null
+
+

If you don't see any output then you can safely assume that there + will be no conflicts when grafting this package.

+

See the comprehensive table above describing how +conflicts are handled for more details.

+
+

Exit Status

+

Graft will terminate with an exit status of either 0, 1, 2, + 3 or 4 under the following conditions:

+
+ + + + + + + +
Exit Status Condition
+
0
+
All operations succeeded.
+
1
+
A conflict occurred during installation.
+
2
+
Command line syntax was incorrect.
+
3
+
One or more packages listed on the command line does not + exist. Other valid packages listed on the command line were processed + correctly.
+
4
+
The log file /var/log/graft could not be updated. + Usually a result of a permission error. Any other error condition will + override this condition.
+
+
+

Using Graft with other package + management tools

+

Most Unix vendors have released their own package management tools + with their operating systems. Examples of this are Solaris 2.x + with its SVR4 Package Manager pkgadd, RedHat Linux + with its RedHat Package Manager rpm, Ubuntu Linux + (and other Debian Linux derivatives) with its dpkg system and + HP-UX 10.x with its swinstall suite. Graft + has been designed as an adjunct to these package managers rather than a + competitor. The author has used Graft successfully with all of + the operating systems mentioned here.

+ +
+

Availability

+

The latest version of Graft should always be available + from:

+
+    http://peters.gormand.com.au/Home/tools/graft
+
+
+

License

+

Graft is licensed under the terms of the GNU General Public + License, Version 2, June 1991.

+

You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or + download it from the Free Software Foundation's web site:

+
+    http://www.gnu.org/copyleft/gpl.html
+    http://www.gnu.org/copyleft/gpl.txt
+
+
+ + + +
+Contents +Previous + + diff --git a/website/manual/en/installation.html b/website/manual/en/installation.html new file mode 100644 index 00000000..75021ecf --- /dev/null +++ b/website/manual/en/installation.html @@ -0,0 +1,14 @@ + + + + + +
+
+ + +

Part II - Installation

+ + + + diff --git a/website/manual/en/installation.t2t b/website/manual/en/installation.t2t new file mode 100644 index 00000000..0851414d --- /dev/null +++ b/website/manual/en/installation.t2t @@ -0,0 +1,5 @@ + + + += Part II - Installation = + diff --git a/website/manual/en/pkgmanagement.html b/website/manual/en/pkgmanagement.html new file mode 100644 index 00000000..75618bc1 --- /dev/null +++ b/website/manual/en/pkgmanagement.html @@ -0,0 +1,4889 @@ + + + + + +
+
+ + +

Part IV - Package management

+ + + + + + +Qi user guide + + + + + + + + + + + + + + + + + +

Qi user guide

+ + + + + + +

Table of Contents

+ +
+ + +
+ + + +
+

+Next: , Up: (dir)   [Contents][Index]

+
+ + +

This user guide is for Qi (version 1.0, +15 April 2019). +

+ + + + + + + + + + + + + +
+

Copyright (C) 2019 Matias Fonzo. +

+

Qi’s home page can be found at http://www.dragora.org. +Send bug reports or suggestions to dragora-users@nongnu.org. +

+
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

1 Introduction

+ + +

Qi is a simple but well-integrated package manager. It can create, +install, remove, and upgrade software packages. Qi produces binary +packages using recipes, which are files containing specific instructions +to build each package from source. Qi can manage multiple packages +under a single directory hierarchy. This method allows to maintain a set +of packages and multiple versions of them. This means that Qi could be +used as the main package manager or complement the existing one. +

+

Qi offers a friendly command line interface, a global configuration +file, a simple recipe layout to deploy software packages; also works +with binary packages in parallel, speeding up installations and packages +in production. The format used for packages is a simplified but safe +POSIX pax archive compressed with lzip. +

+

Qi is a modern (POSIX-compliant) shell script released under the +terms of the GNU General Public License. There are only two major +dependencies for the magic: graft(1) and tarlz(1), the rest is expected +to be found in any Unix-like system. +

+
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

2 Invoking qi

+ + +

This chapter describes the synopsis and command line options for +invoke Qi. +

+
+
Usage: qi [OPTION]... [FILE]...
+
+ +

One mandatory option specifies the operation that ‘qi’ should +perform, other options are meant to detail how this operation should be +performed. +

+

qi supports the following options to operate: +

+
+
-b
+

Build package using recipe names. +

+
+
-c
+

Create .tlz package from directory. +

+
+
-d
+

Delete packages. +

+
+
-i
+

Install packages. +

+
+
-o
+

Resolve build order through .order files. +

+
+
-u
+

Update packages (implies -i, -d and -p options). +

+
+
-w
+

Warn about files that will be linked. +

+
+
-x
+

Extract a package for debugging purposes. +

+
+ +

There are common options between modes: +

+
+
-N
+

Do not read the configuration file. +

+

This will ignore any value in the qirc file. +

+
+
-P <DIR>
+

Package directory for installations. +

+

This option sets ‘${packagedir}’. +

+

Only valid for -i, -d, or -u options. +

+
+
-f
+

Force option. +

+

This option can force the build of a recipe, or force the update of a +pre-existing package. +

+

Only valid for -b, -u options. +

+
+
-t <DIR>
+

Target directory for symbolic links. +

+

This option sets ‘${targetdir}’. +

+

Only valid for -i, -d, or -u options. +

+
+
-k
+

Keep (don’t delete) ‘${srcdir}’ or ‘${destdir}’ in build +mode, keep (don’t delete) package directory in delete mode. +

+

Only valid for -b, -d or -u options. +

+
+
-p
+

Prune conflicts on package installations. +

+

This option may proceed with the package installation if one or more +conflicts occur. +

+
+
-r /rootdir
+

Use the fully qualified named directory as the root directory for all qi +operations. The target directory and package directory will be relative +to the specified directory, including the log file for graft. +

+
+
-v
+

Be verbose (a 2nd -v gives more). +

+
+ +

Options for build mode (-b): +

+
+
-O <DIR>
+

Where the packages produced are written. +

+

This option sets ‘${outdir}’. +

+
+
-W <DIR>
+

Where archives, patches, and recipes are expected. +

+

This option sets ‘${worktree}’. +

+
+
-Z <DIR>
+

Where (compressed) sources will be found. +

+

This option sets ‘${tardir}’. +

+
+
-a
+

Architecture to use. +

+

Default value is obtained via uname(1) as ‘uname -m’. +

+
+
-j
+

Parallel jobs for the compiler. +

+

If not specified, default sets to 1. +

+
+
-1
+

Increment release number (‘${release}’ + 1). +

+

It will be omitted if the -n option is being used. +

+
+
-n
+

Don’t create a .tlz package. +

+
+
-S
+

Selects the option to skip completed recipes. +

+

This means, in interactive mode, when the dialog +to summarize recipes is shown. +

+
+ +

Informative options: +

+
+
-L
+

Print default directory locations. +

+

This will print the target directory, package directory, working tree, +the directory for tarballs, and the output directory for the packages +produced. +

+
+
-h
+

Display the help describing the options and then exit. +

+
+
-V
+

Print the version number and license information. +The version number should be included in all bug reports. +

+
+ +

Expected non-option arguments are package directories and regular files: +recipes or files ending in .tlz, .order. When FILE is -, qi can read from +the standard input. See examples in Packages. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

3 The qirc file

+ + +

The global qirc file offers a way to define variables and tools +(such as a download manager) for default use. This file is used by qi +at runtime, e.g., to build, install, remove or upgrade packages. +

+

It has the following rules: +

+ + +

The command line options related to the package directory and target +directory plus some of the options used for the build mode can override +some values in qirc. See Invoking qi. +

+

The order in which qi looks for this file is: +

+
    +
  1. ${HOME}/.qirc + Effective user. + +
  2. ${sysconfdir}/qirc’ + System-wide. +
+ +

If you intend to run qi as effective user, the file +‘${sysconfdir}/qirc’ could be copied to ${HOME}/.qirc +setting the paths for ‘${packagedir}’ and ‘${targetdir}’ +according to the $HOME. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

4 Packages

+ + +

A package is a suite of programs usually distributed in binary form +which may also contain manual pages, documentation, or any other file +associated to a specific software. +

+

The package format used by qi is a simplified POSIX pax archive +compressed with lzip. The file extension for packages is ‘.tlz’. +

+

Both package installation and package de-installation are managed using +two important (internal) variables: ‘${packagedir}’ and +‘${targetdir}’, these values can be changed in the +configuration file or via options. +

+

${packagedir}’ is a common directory tree where the package +contents will be decompressed (will reside). +

+

${targetdir}’ is a target directory where the links will be +made by graft(1) taking ‘${packagedir}/package_name’ into account. +

+

Packages are installed in self-contained directory trees and symbolic +links from a common area are made to the package files. This allows +multiple versions of the same package to coexist on the same system. +

+ +

4.1 Package conflicts

+ + +

All the links to install or remove a package are handled by graft(1). +Since multiple packages can be installed or removed at the same time, +certain conflicts may arise between the packages. +

+

graft1 +defines a CONFLICT as one of the following conditions: +

+ + +

The default behavior of qi for an incoming package is to ABORT if a +conflict arises. When a package is going to be deleted, qi tells to +graft(1) to remove those parts that are not in conflict, leaving the +links to the belonging package. This behavior can be forced if the +-p option is given. +

+ +

4.2 Installing packages

+ + +

To install a single package, simply type: +

+
+
qi -i coreutils-8.30-i586+1.tlz
+
+ +

To install multiple packages at once, type: +

+
+
qi -i gcc-8.3.0-i586+1.tlz rafaela-2.2-i586+1.tlz ...
+
+ +

Warn about the files that will be linked: +

+
+
qi -w bash-5.0-i586+1.tlz
+
+ +

This is to verify the content of a package before installing it. +

+

See the process of an installation (very verbose): +

+
+
qi -i -v mariana-3.0-i586+1.tlz
+
+ +

A second -v gives more. +

+

Installing package in a different location: +

+
+
qi -r /media/floppy -i lzip-1.21-i586+1.tlz
+
+ +

The -r option assumes ‘${targetdir}’ and ‘${packagedir}’. +See: +

+
+
qi -r /home/selk -P /pkgs -t / -i lzip-1.21-i586+1.tlz
+
+ +

In this case the content of "lzip-1.21-i586+1.tlz" will be decompressed +into ‘/home/selk/pkgs/lzip-1.21-i586+1’. Assuming that the main +binary for lzip is under ‘/home/selk/pkgs/lzip-1.21-i586+1/usr/bin/’ +the target for "usr/bin" will be created at ‘/home/selk’. Considering +that you have exported the PATH as ‘${HOME}/usr/bin’, now the +system is able to see the recent lzip. +

+

Installing from a list of packages using standard input: +

+
+
cat FILELIST.txt | qi -i -
+
+ +

The list of packages must contain full path names to be passed in the +installation, e.g.: +/var/cache/qi/packages/x86_64/devel/tcl-8.6.9-x86_64+1.tlz +/var/cache/qi/packages/x86_64/devel/tk-8.6.9.1-x86_64+1.tlz +/var/cache/qi/packages/x86_64/devel/vala-0.42.3-x86_64+1.tlz +

+ +

4.3 Removing packages

+ + +

To remove a package, simply type: +

+
+
qi -d xz-5.2.4-i586+1.tlz
+
+ +

Delete mode will match the package name using ‘${packagedir}’ as +prefix. For example, if the value of ‘${packagedir}’ is set to +/usr/local/pkgs, this will be equal to: +

+
+
qi -d /usr/local/pkgs/xz-5.2.4-i586+1
+
+ +

Detailed output (very verbose): +

+
+
qi -d -v /usr/local/pkgs/xz-5.2.4-i586+1
+
+ +

A second -v gives more. +

+

By default the delete mode does not preserve a package directory after +removing its links from ‘${targetdir}’, but this behavior can be +changed if the -k option is passed: +

+
+
qi -d -k /usr/local/pkgs/lzip-1.21-i586+1
+
+ +

This means that the links to the package can be reactivated, later: +

+
+
cd /usr/local/pkgs && graft -i lzip-1.21-i586+1
+
+ +

Removing package from a different location: +

+
+
qi -r /home/cthulhu -P /pkgs -t / -d xz-5.2.4-i586+1
+
+ +

Removing a package using standard input: +

+
+
echo "vala-0.42.3-x86_64+1" | qi -d -
+
+ +

This will match with the package directory. +

+ +

4.4 Upgrading packages

+ + +

The upgrade mode inherits the properties of the installation and removal +process. To make sure that a package is updated, the package is installed +in a temporary directory taking ‘${packagedir}’ into account. Once +the incoming package is pre-installed, qi can proceed to search and delete +packages that have the same name (considered as previous ones). Finally, +the package is re-installed at its final location and the temporary +directory is removed. +

+

To upgrade a package, just type: +

+
+
qi -u gcc-9.0.1-i586+1.tlz
+
+ +

This will proceed to update "gcc-9.0.1-i586+1" removing other versions +of "gcc" (if any). +

+

If you want to keep the package directories of versions found during the +upgrade process, just pass: +

+
+
qi -u -k gcc-9.0.1-i586+1.tlz
+
+ +

To see the upgrade process (very verbose): +

+
+
qi -u -v gcc-9.0.1-i586+1.tlz
+
+ +

A second -v gives more. +

+

To force the upgrade of an existing package: +

+
+
qi -u -f gcc-9.0.1-i586+1.tlz
+
+ + +

4.4.1 Package blacklist

+ + +

To implement general package facilities, either to install, remove or +maintain the hierarchy of packages in a clean manner, qi makes use of the +pruning operation via graft(1): +

+

There is a risk if those are crucial packages for the proper functioning +of the system, because it implies the deactivation of symbolic from the +target directory, especially when transitioning an incoming package +into its final location during upgrade. +

+

A blacklist of package names has been devised for the case where +a user decides to upgrade all packages in the system, or +just the crucial ones, such as the C library. +

+

The blacklist is related to the upgrade mode only, consists in installing +a package instead of updating it or removing previous versions of it; +the content of the package will be updated over the existing content at +‘${packagedir}’, while the existing links from +‘${targetdir}’ will be preserved. A pruning of links will be +carried out in order to re-link possible differences with the recent +content, this helps to avoid leaving dead links in the target directory. +

+

Since the upgrade mode is also used to install a new package, the mechanism +for blacklist is to install a declared package if it does not already +exist. If it already exists, it is verified that the binary package is +newer than the package directory in order to perform an update. +

+

Package names for the blacklist can be set from the configuration file. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

5 Recipes

+ + +

A recipe is a file telling qi what to do. Most often, the recipe tells +qi how to build a binary package from a source tarball. +

+

A recipe has two parts: a list of variable definitions and a list of +sections. By convention, the syntax of a section is: +

+
+
section_name()
+{
+    section lines
+}
+
+ +

The section name is followed by parentheses, one newline and an opening +brace. The line finishing the section contains just a closing brace. +The section names or the function names currently recognized are +‘build’. +

+

The ‘build’ section is an augmented shell script. This is the main +section (or shell function) which contains the instructions to +build and produce a package. +

+ +

5.1 Variables

+ + +

A "variable" is a shell variable defined either in qirc +or in a recipe to represent a string of text, called the variable’s +"value". These values are substituted by explicit request in the +definitions of other variables or in calls to external commands. +

+

Variables can represent lists of file names, options to pass to +compilers, programs to run, directories to look in for source files, +directories to write output to, or anything else you can imagine. +

+

Definitions of variables in qi have four levels of precedence. +Options which define variables from the command-line override those +specified in the qirc file, while variables defined in the recipe +override those specified in qirc, taking priority over those +variables set by command-line options. Finally, the variables have +default values if they are not defined anywhere. +

+

Options that set variables through the command-line can only reference +variables defined in qirc and variables with default values. +

+

Definitions of variables in qirc can only reference variables +previously defined in qirc and variables with default values. +

+

Definitions of variables in the recipe can only reference variables +set by the command-line, variables previously defined in the recipe, +variables defined in qirc, and variables with default values. +

+ +

5.2 Special variables

+ + +

There are variables which can only be set using the command line options or +via qirc, there are other special variables which can be defined or +redefined in a recipe. See the following definitions: +

+

outdir’ is the directory where the packages produced are written. +This variable can not be redefined in the recipe. Default sets to +‘/var/cache/qi/packages’. +

+

worktree’ is the working tree where archives, patches, and recipes +are expected. This variable can not be redefined in the recipe. Default +sets to ‘/usr/src/qi’. +

+

tardir’ is defined in the recipe to the directory where the tarball +containing the source can be found. The full name of the tarball is +composed as ‘${tardir}/$tarname’. Its value is available in the +recipe as ‘${tardir}’; a value of . for ‘tardir’ sets it to +the value of CWD (Current Working Directory), this is where the recipe +lives. +

+

arch’ is the architecture to compose the package name. Its value is +available in the recipe as ‘${arch}’. Default value is the output +of ‘uname -m’. +

+

jobs’ is the number of parallel jobs to pass to the compiler. Its +value is available in the recipe as ‘${jobs}’. The default value +is 1. +

+

The two variables ‘${srcdir}’ and ‘${destdir}’ can be +set in the recipe, as any other variable, but if they are not, qi uses +default values for them when building a package. +

+

srcdir’ contains the source code to be compiled, and defaults to +‘${program}-${version}’. ‘destdir’ is the place where the +built package will be installed, and defaults to +‘${TMPDIR}/package-${program}’. +

+

If ‘pkgname’ is left undefined, the special variable ‘program’ +is assigned by default. If ‘pkgversion’ is left undefined, the +special variable ‘version’ is assigned by default. +

+

pkgname’ and ‘pkgversion’ along with: ‘version’, ‘arch’, +and ‘release’ are used to produce the name of the package in the form: +‘${pkgname}-${pkgversion}-${arch}+${release}.tlz’ +

+

A special variable called ‘replace’ can be used to declare package +names that will be replaced at the time of installation. +

+

A typical recipe contains the following variables: +

+ + +

Obtaining sources over the network must be declared in the recipe using +the ‘fetch’ variable. Use double quotes for separated values. +

+

The variables ‘netget’ and ‘rsync’ can be defined in qirc +to establish a network downloader in order to get the sources. If they +are not defined, qi uses default values: +

+

netget’ is the general network downloader tool, defaults sets to +‘wget -c -w1 -t3 --no-check-certificate’. +

+

rsync’ is the network tool for sources containing the prefix for +the RSYNC protocol, default sets to +‘rsync -v -a -L -z -i --progress’. +

+

The variable ‘description’ is used to print the package description +when a package is installed. +

+

A description has two parts: a brief description, and a long description. +By convention, the syntax of ‘description’ is: +

+
+
description="
+Brief description.
+
+Long description.
+"
+
+ +

The first line of the value represented is a brief description of the +software (called "blurb"). A blank line separates the brief +description from the long description, which should contain a more +descriptive description of the software. +

+

An example looks like: +

+
+
description="
+The GNU core utilities.
+
+The GNU core utilities are the basic file, shell and text manipulation
+utilities of the GNU operating system.  These are the core utilities
+which are expected to exist on every operating system.
+"
+
+ +

Please consider a length limit of 78 characters as maximum, because the same +one would be used on the meta file creation. See +The meta file section. +

+

The ‘homepage’ variable is used to declare the main site or home page: +

+
+
homepage=http://www.gnu.org/software/gcc
+
+ +

The variable ‘license’ is used for license information2. +Some code in the program can be covered by license A, license B, or +license C. For "separate licensing" or "heterogeneous licensing", we +suggest using | for a disjunction, & for a conjunction +(if that ever happens in a significant way), and comma for heterogeneous +licensing. Comma would have lower precedence, plus added special terms. +

+
+
license="LGPL, GPL | Artistic + added permission"
+
+ + +

5.3 Writing recipes

+ + +

Originally, qi was designed for the version 3 of Dragora GNU/Linux (this +does not mean that you can use it in another distribution). Therefore we +will put here some references where you will be able to find real and +complete examples to write good recipes: +

+

http://git.savannah.nongnu.org/cgit/dragora.git/tree/recipes. +http://notabug.org/dragora/dragora/src/master/recipes. +

+

You can also check the "doc" directory in the distribution sources of qi +for some examples. +

+ +

5.4 Building packages

+ + +

A recipe is any valid regular file. Qi sets priorities for reading a +recipe, the order in which qi looks for a recipe is: +

+
    +
  1. Current working directory. + +
  2. If the specified path name does not contain "recipe" as the last +component. Qi will complete it by adding "recipe" to the path name. + +
  3. If the recipe is not in the current working directory, it will be +searched under ‘${worktree}/recipes’. The last component will be +completed adding "recipe" to the specified path name. +
+ +

To build a single package, type: +

+
+
qi -b x-apps/xterm
+
+ +

Multiple jobs can be passed to the compiler to speed up the build process: +

+
+
qi -b -j3 x-apps/xterm
+
+ +

Update or install the package produced (if it is not already installed) +when finish: +

+
+
qi -b -j3 -u x-apps/xterm
+
+ +

Only process a recipe but do not create the binary package: +

+
+
qi -b -n dict/aspell
+
+ +

The options -i or -u have no effect when -n is given. +

+

This can be useful to inspect the build process of recipe: +

+

qi -b -k -n dict/aspell 2>&1 | tee aspell-buildlog.txt +

+

The -k option could preserve the source directory and the destination +directory for later inspection. A log file of the build process will be +created redirecting both, standard error and standard output to tee(1). +

+ +

5.5 Variables from the environment

+ + +

Qi has environment variables which can be used at build time: +

+

The variable TMPDIR sets the temporary directory for sources, which is +used for package extractions (see Examining packages) and is +prepended to the value of ‘${srcdir}’ and ‘${destdir}’ in +build mode. By convention its default value is equal to +‘/usr/src/qi/build’. +

+

The variables QICFLAGS, QICXXFLAGS, and QILDFLAGS have +no effect by default. The environment variables such as CFLAGS, +CXXFLAGS, and LDFLAGS are unset at compile time: +

+

Recommended practice is to set variables in the command line of +‘configure’ or make(1) instead of exporting to the +environment. As follows: +

+
+

Variables not defined in a site shell script can be set in the environment +passed to configure. However, some packages may run configure again +during the build, and the customized values of these variables may be +lost. In order to avoid this problem, you should set them in the +configure command line, using ‘VAR=value’. For example: +

+

./configure CC=/usr/local2/bin/gcc +

+

http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Defining-Variables.html +

+ +
+

Indeed, while configure can notice the definition of CC in +‘./configure CC=bizarre-cc’, it is impossible to notice it in +‘CC=bizarre-cc ./configure’, which, unfortunately, is what most +users do. +

+

[...] +

+

configure: error: changes in the environment can compromise the build. +

+

http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Setting-Output-Variables.html +

+ +
+

It is not wise for makefiles to depend for their functioning on +environment variables set up outside their control, since this would cause +different users to get different results from the same makefile. This is +against the whole purpose of most makefiles. +

+

http://gnu.org/software/make/manual/make.html#Environment +

+ + +

5.6 The meta file

+ + +

The "meta file" is a regular file created during the build mode, it +contains information about the package such as program name, program +version, release, fetch address, description, and other minor data +extracted from processed recipes. The name of the file is generated as +‘${full_pkgname}.tlz.txt’, and its purpose is to reflect essential +information to the user without having to look inside the package content. +

+

The content of a meta file looks like: +

+
+
#
+# The Bourne Again SHell.
+#
+# Bash is an sh-compatible shell that incorporates useful features from
+# the Korn shell (ksh) and C shell (csh).  It is intended to conform to
+# the IEEE POSIX P1003.2/ISO 9945.2 shell and tools standard.
+#
+# It offers functional improvements over sh for both programming and
+# interactive use.
+#
+
+QICFLAGS="-g0 -Os -mtune=generic -pipe"
+QICXXFLAGS="-g0 -Os -mtune=generic -pipe"
+QILDFLAGS="-s"
+program=bash
+version=5.0
+release=1
+blurb="The Bourne Again SHell."
+homepage="http://www.gnu.org/software/bash"
+license="GPLv3+"
+fetch="ftp://ftp.gnu.org/gnu/bash/bash-5.0.tar.gz"
+replace=""
+
+ +

Package descriptions are extracted from the variable ‘description’: +each line is interpreted literally and pre-formatted to fit in (exactly) +80 columns, plus the character ‘#’ and a space is prefixed +to every line. +

+

In addition to the Special variables, there are implicit variables such as +‘blurb’: +

+

The ‘blurb’ variable is related to the special variable +‘description’. Its value is composed using the first (substantial) +line of ‘description’, mentioned as the "brief description". +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

6 Order files

+ + +

The order mode has the purpose of resolving the build order through +.order files. An order file contains a list of recipe names, by default +does not perform any action other than to print a resolved list in +descending order. For example, if a depends on b and +c, and c depends on b as well, the file might +look like: +

+
+
a: c b
+b:
+c: b
+
+ +

Each letter represents a recipe name, complete dependencies for +the first recipe name are listed in descending order, which is +printed from right to left, and removed from left to right: +

+

OUTPUT +

+
+
b
+c
+a
+
+ +

Blank lines, colons and parentheses are simply ignored. Comment lines +beginning with ‘#’ are allowed. +

+

An order file could be used to build a series of packages, for example, +if the content is: +

+
+
# Image handling libraries
+
+libs/libjpeg-turbo: devel/nasm
+x-libs/jasper: libs/libjpeg-turbo
+libs/tiff: libs/libjpeg-turbo
+
+ +

To proceed with each recipe, we can type: +

+
+
qi -o imglibs.order | qi -b -i -
+
+ +

The output of ‘qi -o imglibs.order’ tells to qi in which order it +should build the recipes: +

+
+
devel/nasm
+libs/libjpeg-turbo
+x-libs/jasper
+libs/tiff
+
+ + +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

7 Creating packages

+ + +

The "creation mode" is an internal function of qi to make new Qi compatible +compatible packages, the creation mode is selected by the -c option. +A package is produced using the contents of the Current Directory, and +the package file is written out. +

+
+
Usage: qi -c [OUTPUT/packagename.tlz]...
+
+ +

The argument for the file name to be written must contain a fully +qualified named directory as the output directory where the package +produced will be written. The file name should be composed using the +full name: name-version-architecture+release.tlz +

+

EXAMPLE +

+
+
cd /usr/local/pkgs
+cd claws-mail-3.17.1-x86_64+1
+qi -c /var/cache/qi/packages/x86_64/local/claws-mail-3.17.1-x86_64+1.tlz
+
+ +

In this case, the package "claws-mail-3.17.1-x86_64+1.tlz" will be written +into ‘/var/cache/qi/packages/x86_64/local/’. +

+

All packages produced are complemented by a checksum file (.sha256). +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

8 Examining packages

+ + +

The "extraction mode" serves to examine binary packages for debugging +purposes. The extraction mode is selected by the -x option. It +decompresses a package into a single directory, verifying its integrity +and preserving its properties. +

+
+
Usage: qi -x [packagename.tlz]...
+
+ +

EXAMPLE +

+
+
qi -x mksh-R56c-x86_64+1.tlz
+
+ +

This action will put the content of "mksh-R56c-x86_64+1.tlz" into a +single directory, this will be a private directory for the user who +

+

requested the action, creation mode will be equal to u=rwx,g=,o= +(0700). The package content will reside on this location, default +mask to deploy the content will be equal to +u=rwx,g=rwx,o=rwx (0000). +

+

The creation of the custom directory is influenced by the value of the +TMPDIR variable. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

9 Exit status

+ + +

All the exit codes are described in this chapter. +

+
+
0
+

Successful completion (no errors). +

+
+
1
+

Minor common errors: +

+
    +
  • - Help usage on illegal options or required arguments. + +
  • - Program needed by qi (prerequisite) is not available. +
+ +
+
2
+

Command execution error: +

+

This code is used to return the evaluation of external commands and shell +arguments in case of error. +

+
+
3
+

Integrity check error for compressed files. +

+

Compressed files means: +

+
    +
  • - Tarball files from tar(1). +Supported extensions: .tar, .tar.gz, .tgz, .tar.Z, .tar.bz2, .tbz2, .tbz, +.tar.xz, .txz + +
  • - Tarball files from tarlz(1). +Supported extensions: .tar.lz, .tlz + +
  • - Zip files from unzip(1). +Supported extensions: .zip, .ZIP + +
  • - Gzip files from gzip(1). +Supported extensions: .gz, .Z + +
  • - Bzip2 files from bzip2(1). +Supported extensions: .bz2 + +
  • - Lzip files from lzip(1). +Supported extensions: .lz + +
  • - Xz files from xz(1). +Supported extensions: .xz +
+ +
+
4
+

File empty, not regular, or expected. +

+

Commonly, it is expected: +

+
    +
  • - An argument for the mode of operation. + +
  • - A readable file or directory. + +
  • - A binary package (.tlz). + +
  • - A valid recipe. + +
  • - An order file (.order). + +
  • - A protocol supported by the network downloader tool. + +
  • - A checksum file (.sha256). +
+ +
+
5
+

Empty or not defined variable: +

+

This code is used to report empty or undefined variables; usually, +variables coming from a recipe or assigned arrays that are tested. +

+
+
6
+

Package already installed: +

+

The package directory for an incoming .tlz package already exists. +

+
+
10
+

Network manager error: +

+

This code is used if the network downloader tool fails for some reason. +

+
+ + +
+ +
+

+Previous: , Up: Top   [Contents][Index]

+
+ +

Index

+ +
Jump to:   C +   +E +   +H +   +I +   +M +   +P +   +R +   +S +   +T +   +V +   +W +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

C
configuration file: The qirc file

E
environment variables: Recipes
exit codes: Exit status

H
handling build order: Order files

I
introduction: Introduction
invocation: Invoking qi

M
managing packages: Packages

P
package blacklist: Packages
package build: Recipes
package conflicts: Packages
package creation: Creating packages
package de-installation: Packages
package examination: Examining packages
package installation: Packages
package upgrade: Packages

R
recipes: Recipes

S
special variables: Recipes

T
the meta file: Recipes

V
variables: Recipes

W
writing recipes: Recipes

+
Jump to:   C +   +E +   +H +   +I +   +M +   +P +   +R +   +S +   +T +   +V +   +W +   +
+ +
+
+

Footnotes

+ +

(1)

+

The official guide for Graft can be found at +http://peters.gormand.com.au/Home/tools/graft/graft.html.

+

(2)

+

The proposal for ‘license’ was made by Richard M. Stallman at +http://lists.gnu.org/archive/html/gnu-linux-libre/2016-05/msg00003.html.

+
+
+ + + + + + + + +Graft + + + + +
+

Graft - a package management utility

+
+ +

Prepared by Peter Samuel +<peter.r.samuel@gmail.com>

+ +

$Revision: 2.16 $

+

$Date: 2018/04/16 14:54:07 $

+ +
+

graft: To insert (a graft) in a branch or stem + of another tree; to propagate by insertion in another stock; also, to + insert a graft upon. To implant a portion of (living flesh or skin) in + a lesion so as to form an organic union. To join (one thing) to another + as if by grafting, so as to bring about a close union.

+
+ +
+ +

Contents

+ + + +
+ +

Introduction

+ +

Graft provides a mechanism for managing multiple packages +under a single directory hierarchy. It was inspired by both Depot +(Carnegie Mellon University) and Stow (Bob Glickstein).

+ +

For the purposes of this discussion a package is defined as +a suite of programs and files that make up an individual product. For +example, the package known as gcc consists of the compiler +and preprocessor programs, include files, manual pages and any other +associated file or program. The concept of a package should not be +confused with some vendor's definitions that are - by this definition - +actually collections of packages.

+ +

Special thanks to Gordon Rowell, Charles Butcher, Charlie Brady, +Robert Maldon and Matias A. Fonzo for design suggestions and contributions. +

+ +
+ +

Rationale

+ +

In any reasonably large environment, many software packages will be +installed. The installation location for these packages usually follows +one of three rationales - each with its own advantages and drawbacks:

+ +
    + +
  1. Each package is isolated from all other packages by + installing it into a self contained directory tree. All binaries, + manual pages, library and configuration files are stored under + a single directory tree. This directory tree contains NO other + files which are not the exclusive domain of the package in + question.

    + +

    This method makes package demarcation obvious. As each + package is self contained, identification of any file within a + package is immediately apparent.

    + +

    Multiple versions of packages can be installed fairly easily + to accommodate acceptance testing of new versions and/or legacy + systems.

    + +

    However, the use of individual package directories can + lead to VERY long $PATH and $MANPATH environment + variables. Some shells may not be able to handle such long + variables. Whenever a new package is added, each user MUST + update their $PATH and $MANPATH to make the package + available.

    + +
  2. Packages are installed under a common directory tree. + Binaries for all packages are grouped in a single directory, + manual pages for all packages in another directory and so on. +

    + +

    This method eliminates the need for continually updating long + $PATH variables for each user. As soon as a package is + placed into the common 'bin' directory it is immediately + available to all users (after a shell rehash if necessary).

    + +

    However, when a package is to be updated it is often very + difficult to isolate all the files related to a particular + package if they are intermingled with unrelated files.

    + +
  3. A combination of methods (1) and (2).

    + +
+ +

In an effort to maximise the advantages and minimise the +disadvantages, Depot, Stow and Graft adopt a similar +philosophy:

+ +
+

Packages are installed in self contained directory trees and + symbolic links from a common area are made to the package files.

+
+ +

This approach allows multiple versions of the same package to co-exist +on the one system. One version is the commonly available version and +symbolic links will be made to this version. New versions can be tested +and once acceptable can replace the current commonly available version. +Older versions can still be used for legacy systems by using the +'real' path name to the package instead of the 'common' +path name.

+ +

The size and complexity of environment variables such as $PATH +and $MANPATH is minimised because only the common area is +required. Any special cases can also be accommodated but these will +usually be in the minority when compared with the number of commonly +available packages.

+ +
+ +

Research

+ +

Note: Development of Graft began in late 1996. The +comments regarding the packages listed below reflect their functionality +and behaviour at that time and may not necessarily reflect their current +functionality and behaviour.

+ +

As stated earlier, Graft was inspired by Depot and +Stow. Both these systems were examined and finally rejected for +the following reasons:

+ +
+ +
Depot + ftp://ftp.andrew.cmu.edu/pub/depot/depot.tar.gz + +

Depot is very flexible yet cumbersome.

+ +

It requires a database file to be created which + provides a snapshot of the current state of both the package + repository and the Depot target. It is possible to + inadvertently destroy the package repository if the database + is damaged.

+ +

Depot assumes "ownership" of the + target area, making it almost impossible to accommodate + packages that are not under the control of Depot. + ("Ownership" in this case means that Depot + assumes ALL files in the target area will be under the + control of Depot. It does not imply that Depot + modifies Unix file permissions).

+ +

Because of Depot's assumed ownership it is + difficult for other packages not under the control of + Depot to be placed in the same target area.

+ +

Depot attempts to impose a fixed package repository + relative to the package target. It assumes that all + packages will be stored under + 'dir/depot/package' and the target + will be 'dir'. This can be overridden on + the command line but the internals of Depot make + this mechanism cumbersome.

+ +

Depot is written in C and there are many source + files in its distribution. Local modifications would be + difficult to quickly implement and test.

+ +
Stow + https://www.gnu.org/software/stow/ + +

Stow is a stateless system. It requires no + database or configuration information.

+ +

Like Depot, it assumes that the package repository + will be stored under 'dir/stow/package' + and the target will be 'dir'. This can be + overridden on the command line and works well during the + install phase.

+ +

Stow assumes "ownership" + of the target area, making it difficult to accommodate + packages that are not under the control of Stow. + ("Ownership" in this case means that Stow + assumes ALL files in the target area will be under the + control of Stow. It does not imply that Stow + modifies Unix file permissions).

+ +

Because of Stow's assumed ownership + it is difficult for other packages not under the control + of Stow to be placed in the same target area. When + deleting packages, Stow examines everything in the + target directory - whether it is associated with the package + it is trying to delete or not. This can be time consuming and + potentially dangerous as empty directories are also removed + - even empty directories that do not belong to the package + being removed.

+ +

Stow has a clever feature of folding and + unfolding directories. It attempts to optimise the + number of symbolic links by making links to directories if + the directory is only associated with a single package. If + at a later date Stow discovers another package that + needs that directory it will unfold that directory + into a collection of symbolic links to files rather than + a single symbolic link to the directory. Stow will + fold the directory when removing packages if the + remainder of the directory is only concerned with a single + package. While clever, this feature is probably a waste of + time and effort. It means that the entire package target + must be scanned to determine package ownership of links and + as packages will usually be replaced by newer versions a + directory fold will probably be short lived.

+ +

Stow will sometimes miss potential conflicts when + run in show only mode. The conflicts may occur when a + directory is unfolded and will not show up in show only + mode.

+ +

Stow's author suggests that packages be compiled + such that they refer to files in the target location rather + than the actual package installation directory. This approach + precludes the use of multiple versions of packages with + different configuration and/or library files.

+ +

Stow is written in Perl and is only a + few hundred lines of code so local modifications can be + accommodated. However there are very few comments in the + code which makes the process of modification difficult.

+ +
+ +

Since the release of Graft 1.6, the existence of yet another +packaging program has been brought to the author's attention.

+ +
+ +
Encap + http://www.ks.uiuc.edu/Development/Computers/docs/sysadmin/Build/encap.html + +

Encap grew out of work begun at the University + of Illinois Champaign-Urbana. It has the same underlying + philosophy as Depot, Stow and Graft - + encapsulate packages into self contained directories and use + symbolic links to make them visible in a common location.

+ +

Encap uses a combination of a csh wrapper + and a Perl program to accomplish its work. Like both + Depot and Stow, Encap assumes that all + compiled packages will live under a single directory hierarchy + - by default 'dir/encap/package'. It + then attempts to create a symbolic link tree for ALL the + packages under this area. There doesn't appear to be any + easy way to support the quick addition or removal of a single + package.

+ +

A new release of Encap incorporating many new + features was expected to be available in early 1997, however + no release greater than version 1.2 has been forthcoming.

+ +

One good feature of Encap is the ability to exclude + specific files from the package tree. This concept has been + incorporated into Graft 1.7 and above.

+ +
+ +

Since the release of Graft 2.3, the existence of +several another packaging programs have been brought to the author's +attention. Rather than outline their features and whether or not the +author feels they are superior (or inferior) to Graft, a reference +to each package and a brief description is given and further research +is left as an exercise for the reader:

+ +
+ +
stowES + +
+ +
+https://os.inf.tu-dresden.de/~adam/stowES/
+
+ +

"stowES (stow Enhancement Script) is + a Perl script which tries to ease the use of the "stow" + packaging program and software which can be compiled and + installed with autoconf. It automates the compilation and + installation of software packages and provides some useful + functions to maintain your stow packages (e.g., list packages, + check packages for integrity, etc.)."

+ +
opt_depot + +
+ +
+https://github.com/jonabbey/opt_depot
+
+ +

"opt_depot is a suite of Perl scripts which makes + it easy to manage installed software across a wide range + of client systems. opt_depot makes it possible to keep all + files associated with a program together in one directory, + so installation and de-installation is simple. opt_depot is + easy to manage, and provides a scheme for installing software + in a truly portable fashion; packages may be installed locally + on client systems, or kept in a central package archive for + NFS access. "

+ +

This site also has links to several other package + management utilities, including Graft.

+ +
relink + +
+ +
+http://sourceforge.net/projects/relink/
+
+ +

"relink is a package management tool for + organization and management of software packages. It should + run on any UNIX platform that runs PERL. Similar tools + include: rpm(REDHAT/Mandrake), pkgadd(Slackware/SUN), + stow(GNU) and depot(CMU)"

+ + +
univSrcPkg + +
+ +
+http://freecode.com/articles/the-universal-source-package
+
+ +

Bud Bruegger has written + a brief paper outlining his thoughts on a "Universal Source + Package" solution.

+ +

This site also has links to other package management + programs and similar items of interest.

+ +
+ +
+ +

Design

+ +

This brings us to Graft. Graft has been designed to +use the best features of Depot, Stow and Encap +while maintaining as simple a mechanism as possible. The principles of +Graft are:

+ + + +

Control file precedence & conflict resolution

+ +

As stated above, the various Graft control files have the +following precedence, from highest to lowest:

+ +
+    .nograft > .graft-exclude > .graft-include > .graft-config
+
+ +

The following table summarises the activities of Graft when +various control files are present:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Install +
+ Target + + .nograft + + .graft-exclude + + .graft-include + + .graft-config +
+ does not exist + + IGNORE + + IGNORE + + SYMLINK + + COPY +
+ symlink to source + + IGNORE + + IGNORE + + NOP + + DELETE & COPY +
+ symlink to other + + IGNORE + + IGNORE + + CONFLICT + + N/A +
+ symlink to other (crc match) + + N/A + + N/A + + N/A + + NOP +
+ symlink to other (crc diff) + + N/A + + N/A + + N/A + + COPY.new +
+ file + + IGNORE + + IGNORE + + CONFLICT + + N/A +
+ file (crc match) + + N/A + + N/A + + N/A + + NOP +
+ file (crc diff) + + N/A + + N/A + + N/A + + COPY.new +
+ not a file + + IGNORE + + IGNORE + + CONFLICT + + CONFLICT +
+ Delete +
+ Target + + .nograft + + .graft-exclude + + .graft-include + + .graft-config +
+ does not exist + + NOP + + NOP + + NOP + + NOP +
+ symlink to source + + DELETE + + DELETE + + DELETE + + DELETE & DELETE.new +
+ symlink to other + + CONFLICT + + CONFLICT + + CONFLICT + + N/A +
+ symlink to other (crc match) + + N/A + + N/A + + N/A + + DELETE.new +
+ symlink to other (crc diff) + + N/A + + N/A + + N/A + + NOP +
+ file + + NOTE + + NOTE + + CONFLICT + + N/A +
+ file (crc match) + + N/A + + N/A + + N/A + + DELETE.new +
+ file (crc diff) + + N/A + + N/A + + N/A + + NOP +
+ not a file + + CONFLICT + + CONFLICT + + CONFLICT + + CONFLICT +
+ Prune +
+ Target + + .nograft + + .graft-exclude + + .graft-include + + .graft-config +
+ does not exist + + NOP + + NOP + + NOP + + N/A +
+ symlink to source + + NOP + + NOP + + NOP + + N/A +
+ symlink to other + + PRUNE + + PRUNE + + PRUNE + + N/A +
+ file + + PRUNE + + PRUNE + + PRUNE + + N/A +
+ not a file + + PRUNE + + PRUNE + + PRUNE + + N/A +
+
+ +
+ +

History

+ +

Development on Graft began in October 1996. The initial design +used a configuration file to map the installed location of each package to +its target directory (that is the directory in which the symbolic links +would be created). Work proceeded at a regular pace and by November 1997 +Graft version 2.1 was released. In this, and all +subsequent versions, the configuration file had been removed in favour of +using default source and target directories.

+ +

No further work was performed until September 2000 when the concept of +bypassing or including files and directories using .nograft or +.graft-include files was introduced in Graft version +2.3.

+ +

Again nothing changed until February 2002 when Rod Whitby identified a +bug in the handling of .graft-include files. Several other users +(Peter Bray, Robert Maldon and others) also reported some deprecation +warnings when using Graft with Perl version +5.6.0. Graft version 2.4 was the end of +Graft development for over a decade.

+ +

In May 2015 Matias A. Fonzo contacted the author wishing to use +Graft in the +Dragora GNU/Linux +distribution. Matias' usage of Graft lead to Graft +version 2.5 in June 2015 whereby the -P command line +option was silently ignored if the effective user was not root.

+ +

Since the release of Graft version 2.4 the author's +Perl code had improved somewhat so Graft version +2.6 released in July 2015 represented a major clean up of coding +style and internals. No new behaviours or features were added to the +2.6 release.

+ +

Matias made some more suggestions and improvements up to and including +Graft version 2.16 in April 2018. These changes added +the .graft-config control file, the -r /rootdir option for +specifying a new root directory, the -L option for displaying +default locations as well as introducing some tighter controls on the +messages and exit status of Graft under various conditions.

+ +
+ +

Installation

+ +

Before installing Graft you'll need Perl +5.x. Graft version 2.x requires features only +available with Perl 5.x and will not run with +Perl 4.x.

+ +

Your operating system and its file system(s) should also support +symbolic links. If you can't make symbolic links then you can't use +Graft! Graft will exit gracefully if your version of +Perl does not support symbolic links. It will also exit gracefully +if you attempt to graft a package into a file system that does not +support symbolic links - from a Linux ext4 file system into an +vfat file system for example.

+ +

Graft has been written to ensure it uses Perl modules +that are considered part of the core Perl distribution. However it +may be possible that you're using a home grown installation of +Perl or some distribution that doesn't have the same Perl +modules as the author's development environment.

+ +

If this is the case you'll see compile failures for the following modules +if they are unavailable:

+ +
+   File::Basename
+   Getopt::Long
+
+ +

You will not be able to install Graft until these modules are +available.

+ +

You may also see run-time failures when using Graft with +.graft-config files if the following modules are unavailable:

+ +
+   Compress::Raw::Zlib    (used in install and delete modes)
+   File::Copy             (only used in install mode)
+
+ +

If you don't have these modules and you do not intend to use +.graft-config files then you can continue to use Graft +without issue.

+ +

Follow these instructions to install Graft:

+ +
    + +
  1. Unpack the gzipped Graft distribution:

    + +
    +    gunzip -c graft-2.16.tar.gz | tar xvf -
    +
    + +
  2. change directories to the Graft distribution + directory:

    + +
    +    cd graft-2.16
    +
    + +
  3. Create an writable version of the Makefile by + running the command

    + +
    +    make -f Makefile.dist
    +
    + +

    You'll see output similar to

    + +
    +    cp Makefile.dist Makefile
    +    chmod 644 Makefile
    +
    +    ######################################################
    +    #                                                    #
    +    #       You'll now need to modify the Makefile       #
    +    #      variables to suit your local conditions.      #
    +    #                                                    #
    +    ######################################################
    +
    +    make: *** [Makefile] Error 1
    +
    + +

    You can ignore the error message. That is just there to + prevent the creation of the graft executable before you've + made your site specific configurations to the Makefile. +

    + +
  4. Edit the Makefile. The following variables should be + modified to suit your local requirements:

    + +
    + +
    +
    +PACKAGEDIR     = /usr/local/pkgs
    +TARGETDIR      = /usr/local
    +
    + +

    These two variables control your default + package installation and target + directories. Most sites will probably choose to + install packages under a common installation + directory and then graft them into a common + target directory.

    + +

    If no specific target directory is + given on the command line, Graft will use + the default value specified by TARGETDIR. If + a target directory is given on the command + line but is not fully qualified, the value specified + by TARGETDIR will be prepended to the command + line argument.

    + +

    Package names provided to Graft that are + not fully qualified will have the value specified + by PACKAGEDIR prepended to the command line + arguments.

    +
    +
    +TOP            = $(PACKAGEDIR)/graft-$(VERSION)
    +BIN            = $(TOP)/bin
    +MAN            = $(TOP)/man
    +DOC            = $(TOP)/doc
    +
    + +

    There should be no need to modify these + values unless you wish to install Graft into + a directory that is different from your default + package installation directory. If you do modify + TOP you should not change the values of + BIN, MAN and DOC. If you feel + you must change these values then perhaps you've + misunderstood the concept behind Graft so a + re-read of this document may be in order.

    + +
    +
    +PERL           = /usr/bin/perl
    +
    + +

    This variable refers to the location + of the Perl 5.x that will be used by + the Graft executable. If you plan on + grafting Perl then this value should + be the grafted location of Perl + rather than the installation location of Perl. + If you are using an operating system that comes with + Perl 5.x - such as RedHat or Ubuntu + Linux - then you don't need to worry about + grafting Perl so the value of + PERL should reflect its installed + location.

    + +

    Most Unix, Linux and other Unix like operating + systems ship with Perl these days so + modifying this value is probably unnecessary.

    + +
    +
    +BUILDPERL      = $(PERL)
    +
    + +

    Perl is required during the + make. You'll only need to change this if + the current installed location of Perl is + different to the future grafted location of + Perl.

    + +
    +
    +LOGFILE                = /var/log/graft
    +
    + +

    Graft logs all of its actions to a log + file. Modify the value of LOGFILE to suit + your local needs. An alternative name can be + specified on the command line.

    + +

    If you want logging disabled by default, set the + value of LOGFILE to /dev/null.

    + +
    +
    +GRAFT-IGNORE   = .nograft
    +GRAFT-EXCLUDE  = .graft-exclude
    +GRAFT-INCLUDE  = .graft-include
    +GRAFT-CONFIG   = .graft-config
    +
    + +

    These variables hold the names of the + special Graft files that control whether or + not subdirectories or files are grafted. If + you change these values, try to choose obvious names. + If you want the files to appear in a simple directory + listing, do not use file names that begin with a + dot "." character.

    + +
    +
    +GRAFT-NEVER    =
    +
    + +

    This variable holds the names of the + files and/or directories that should never be + grafted. Typically these may be source code + repositories as used by systems such as + CVS, or perhaps lockfiles. The default + value is empty but if you wish to specify values, + simply add them to the variable using only + whitespace as a separator. For example:

    + +
    +GRAFT-NEVER     = CVS RCS SCCS .lock
    +
    + +
    +
    +NEVERGRAFT     = 0
    +
    + +

    If this variable is set to 1, + the files and/or directories specified by + GRAFT-NEVER will be automatically excluded + from the grafted directory.

    + +

    If this variable is set to 0, the files + and/or directories specified by GRAFT-NEVER + will be not be excluded from the grafted + directory.

    + +

    The sense of this value is reversed by use of + the -C command line option. + +

    The automatic exclusion is bypassed completely + if the grafted directory contains either + a .nograft or .graft-include + file.

    + +
    +
    +PRUNED-SUFFIX  = .pruned
    +
    + +

    This variable sets the suffix name of + pruned files. Pruned files will be + renamed filename.pruned.

    + +
    +
    +CONFIG-SUFFIX  = .new
    +
    + +

    This variable sets the suffix name of configuration + files that will be copied to the target directory when + the target object is in conflict with the package + object. The files will be copied as + filename.new.

    + +
    +
    +SUPERUSER      = 1
    +
    + +

    If this variable is set to 1 only + the superuser can install, delete + or prune packages. This can be overridden + by the use of the -u command line + option. If this variable is set to 0, + superuser privileges are not required and the + -u override command line option is + disabled.

    + +

    If you are installing a private copy of + Graft to manage packages in your home + directory you should set SUPERUSER to + 0.

    + +

    If you're using Graft to manage a global + set of packages you should set SUPERUSER + to 1.

    + +
    +
    +PRESERVEPERMS  = 0
    +
    + +

    When grafting packages, Graft + will create new directories as required. By setting + PRESERVEPERMS to 1, + the original user id, group id and file modes will be + carried over to the new directory. This variable is + used only if SUPERUSER is set to + 1. The sense of this variable can be + reversed using the -P command line + option.

    + +
    +
    +DELETEOBJECTS  = 0
    +
    + +

    When deleting grafted packages, + Graft may leave empty directories. Setting + DELETEOBJECTS to 1 + will allow Graft to delete these directories. + If DELETEOBJECTS is 0 + then Graft will display an appropriate message + reminding the user that a directory has been emptied. + The sense of this variable can be reversed using the + -D command line option.

    + +

    It's probably not good practise to set this value + to 1 as some directories may be used + as place holders by a number of different packages. If + the value is set to 0 deletion of + directories can be forced via the -D + command line option.

    + +

    When pruning packages, graft can either + remove conflicting files or rename them. If + DELETEOBJECTS is set to + 1 the default prune action will be to + delete conflicting objects. If + DELETEOBJECTS is set to + 0 the default prune action will be to + rename conflicting objects. The sense of this variable + can be reversed using the -D command + line option.

    + +
    + +

    Save your changes and exit from the editor.

    + +
  5. Remove any existing executables by running:

    + +
    +    make clean
    +
    + +

    You should see output similar to:

    + +
    +    rm -f graft
    +
    + +
  6. Create the Graft executable by running:

    + +
    +    make
    +
    + +

    You should see output similar to:

    + +
    +    /usr/bin/perl -wc graft.pl
    +    graft.pl syntax OK
    +    sed                                         \
    +        -e 's#xCONFIG-SUFFIXx#.new#g'           \
    +        -e 's#xDELETEOBJECTSx#0#g'              \
    +        -e 's#xGRAFT-CONFIGx#.graft-config#g'   \
    +        -e 's#xGRAFT-EXCLUDEx#.graft-exclude#g' \
    +        -e 's#xGRAFT-IGNOREx#.nograft#g'        \
    +        -e 's#xGRAFT-INCLUDEx#.graft-include#g' \
    +        -e 's#xGRAFT-NEVERx##g'                 \
    +        -e 's#xLOGFILEx#/var/log/graft#g'       \
    +        -e 's#xNEVERGRAFTx#0#g'                 \
    +        -e 's#xPACKAGEDIRx#/usr/local/pkgs#g'   \
    +        -e 's#xPERLx#/usr/bin/perl#g'           \
    +        -e 's#xPRESERVEPERMSx#0#g'              \
    +        -e 's#xPRUNED-SUFFIXx#.pruned#g'        \
    +        -e 's#xSUPERUSERx#1#g'                  \
    +        -e 's#xTARGETDIRx#/usr/local#g'         \
    +        < graft.pl > graft
    +    chmod +x graft
    +    /usr/bin/perl -wc graft
    +    graft syntax OK
    +    if [ -n "" ];                                       \
    +    then                                                \
    +        AUTOIGNORE=1;                                   \
    +    else                                                \
    +        AUTOIGNORE=0;                                   \
    +    fi;                                                 \
    +    sed                                                 \
    +        -e "s#xAUTOIGNOREx#$AUTOIGNORE#g"               \
    +        -e 's#xCONFIG-SUFFIXx#.new#g'                   \
    +        -e 's#xDELETEOBJECTSx#0#g'                      \
    +        -e 's#xDOCx#/usr/local/pkgs/graft-2.16/doc#g'   \
    +        -e 's#xGRAFT-CONFIGx#.graft-config#g'           \
    +        -e 's#xGRAFT-EXCLUDEx#.graft-exclude#g'         \
    +        -e 's#xGRAFT-IGNOREx#.nograft#g'                \
    +        -e 's#xGRAFT-INCLUDEx#.graft-include#g'         \
    +        -e 's#xGRAFT-NEVERx##g'                         \
    +        -e 's#xLOGFILEx#/var/log/graft#g'               \
    +        -e 's#xNEVERGRAFTx#0#g'                         \
    +        -e 's#xPACKAGEDIRx#/usr/local/pkgs#g'           \
    +        -e 's#xPERLx#/usr/bin/perl#g'                   \
    +        -e 's#xPRESERVEPERMSx#0#g'                      \
    +        -e 's#xPRUNED-SUFFIXx#.pruned#g'                \
    +        -e 's#xSUPERUSERx#1#g'                          \
    +        -e 's#xTARGETDIRx#/usr/local#g'                 \
    +        -e 's#xVERSIONx#2.16#g'                         \
    +        < graft.man > graft.1
    +
    + +
  7. If you're using the automounter under Solaris + 2.x, the installation process may not be able to directly + create the directory specified by TOP. If this is the case + then manually create this directory using whatever procedures + are appropriate for your operating system.

    + +

    For example, if the /usr/local mount point is under the + control of the automounter via an entry in the + auto_pkgs map:

    + +
    +    *   nfshost:/export/sparc-SunOS-5.5.1/usr/local/&
    +
    + +

    you'll need to create the Graft installation directory + by executing the following command on the machine nfshost: +

    + +
    +    mkdir /export/sparc-SunOS-5.5.1/usr/local/pkgs/graft-2.16
    +
    + +
  8. Install the Graft executable, manual page and + documentation by executing:

    + +
    +    make install
    +
    + +

    You should see output similar to:

    + +
    +    mkdir -p /usr/local/pkgs/graft-2.16/bin
    +    cp graft /usr/local/pkgs/graft-2.16/bin
    +
    +    for i in graft.1;                                              \
    +    do                                                             \
    +        manpage=`basename $i`;                                     \
    +        man=`expr $i : '.*\.\(.\)'`;                               \
    +        mkdir -p /usr/local/pkgs/graft-2.16/man/man$man;           \
    +        cp $i /usr/local/pkgs/graft-2.16/man/man$man/$manpage;     \
    +        chmod 644 /usr/local/pkgs/graft-2.16/man/man$man/$manpage; \
    +    done
    +
    +    for i in graft.html graft.pdf graft.ps graft.txt;              \
    +    do                                                             \
    +        mkdir -p /usr/local/pkgs/graft-2.16/doc;                   \
    +        cp doc/$i /usr/local/pkgs/graft-2.16/doc;                  \
    +        chmod 644 /usr/local/pkgs/graft-2.16/doc/$i;               \
    +        touch /usr/local/pkgs/graft-2.16/doc/.nograft;             \
    +    done
    +
    + +
+ +

Graft is now installed and ready to be used.

+ +

NOTE: If you make changes to your Graft installation at a +later date, please run the following commands:

+ +
+    make clean
+    make install
+
+ +

Failure to do this may result in a Graft manual page that does +NOT reflect your current configuration.

+ +

Creating RPM and DEB packages

+ +

Beginning with Graft 2.11 there is now the ability to create +RPM and Debian installation packages. Obviously you'll need one or more of +the rpmbuild and dpkg-deb packages installed on your +system.

+ +

After editing the Makefile to suit your environment simply run +the appropriate make command to create the binary installation +package in the current directory:

+ +
+    make rpm
+
+ +

or

+ +
+    make deb
+
+ +

The creation of these packages is somewhat experimental. Please let the +author know if you have issues.

+ +
+ +

Grafting Graft and Perl - the +bootstrap problem

+ +

If you are using an operating system that comes with Perl +5.x - such as RedHat or Ubuntu Linux - then you don't need to worry +about grafting Perl, so this section can be ignored.

+ +

However if you are a creator of an operating system +distribution then this section may be relevant.

+ +

Embedded into the Graft executable is the location of the +Perl executable. If you've understood the concept behind +Graft then this location may be the grafted location of +Perl rather than the true location of Perl.

+ +

This presents a dilemma when you come to graft both Graft +and Perl. You can't run the grafted location of the +Graft executable because it doesn't exist yet, and you can't run +the real location of the Graft executable because Perl +hasn't been grafted yet.

+ +

Assuming that Graft and Perl are installed in

+ +
+    /usr/local/pkgs/graft-2.16
+    /usr/local/pkgs/perl-5.18.2
+
+ +

you can resolve this dilemma by executing the following commands: +

+ +
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i graft-2.16
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i perl-5.18.2
+
+ +

This will graft both Graft and Perl from the +default package installation directory (as specified by +PACKAGEDIR in the Makefile) into your default target +directory (as specified by TARGETDIR in the Makefile). +

+ +

If you don't wish to use the default directories you can use the +following commands to graft the packages into /pkgs +instead of /usr/local for example:

+ +
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i -t /pkgs /usr/local/pkgs/graft-2.16
+    /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i -t /pkgs /usr/local/pkgs/perl-5.18.2
+
+ +

Now both Graft and Perl have been grafted and any +other package can be grafted by executing the simpler command: +

+ +
+    graft -i package
+
+ +

The Graft distribution includes a program called +graftBootStrap.sh which allows you to easily graft both +Graft and Perl. It can be found in the contrib +directory of the distribution. Thanks to Gordon Rowell for providing it.

+ +

You may also find the -L command line option to be useful to +programmatically determine where Graft expects to find +Perl along with the default locations of its log file, target and +package directories. See the Information section +below for details.

+ +
+ +

Using Graft

+ +

Compiling Packages

+ +

Any packages you wish to place under the control of Graft should +be compiled and installed in such a way that any package dependent +files are referenced with the ACTUAL package installation directory +rather than the common area in which Graft will be creating +symbolic links. For example, ensure that Perl version +5.18.2 is looking for its library files in +/usr/local/pkgs/perl-5.18.2/lib/perl5 instead of +/usr/local/lib/perl5. This approach will allow you to easily +separate multiple versions of the same package without any problems.

+ +
+ +

Graft command line options

+ +

All of the details concerning actions, package locations and target +directories are passed to Graft on the command line. +(Graft 1.x used a configuration file. This has now been +deprecated in favour of a log file).

+ +

Graft's command line options can be summarised as:

+ +
+    graft -i [-P|u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -d [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -p [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
+    graft -L
+
+ +

Graft has four basic actions:

+ +
    + +
  1. Install

    + +
    +    graft -i [-C] [-P|u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    + +
    + +
    -i +
    +

    Install symbolic links from the package + installation directory to the target directory. + Requires superuser privileges if + SUPERUSER was set to 1 in the + Makefile.

    + +
    -C +
    +

    If NEVERGRAFT was set to 1 + in the Makefile, disable the automatic + exclusion of files and/or directories whose + names exactly match the values specified by + GRAFT-NEVER in the Makefile.

    + +

    If NEVERGRAFT was set to 0 + in the Makefile, force the automatic + exclusion of files and/or directories whose + names exactly match the values specified by + GRAFT-NEVER in the Makefile.

    + +

    Can only be used with the -i option.

    + +

    This option is ignored for each grafted + directory, if the directory contains a + .nograft or .graft-include + file.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. If there + are no objects specified for + GRAFT-NEVER then this option will + be silently ignored and will not appear in the help + message nor in the manual page.

    + +
    -P +
    +

    Preserve modes and ownerships when creating new + directories or copying files if + PRESERVEPERMS was set to + 0 in the Makefile. Do not + preserve modes and ownerships if the option is not + provided on the command line.

    + +

    Do not preserve modes and ownerships when + creating new directories or copying files if + PRESERVEPERMS was set to + 1 in the Makefile. + Preserve modes and ownerships if the option is not + provided on the command line.

    + +

    Cannot be used with the -u option.

    + +

    This option will be silently ignored if the + effective user of Graft is not root.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. This + option will be silently ignored and will not appear + in the help message nor in the manual page if + SUPERUSER was set to + 0 in the Makefile.

    + +
    -u +
    +

    Superuser privileges are not required when + installing packages.

    + +

    Cannot be used with the -P option.

    + +

    This option is only available if + SUPERUSER was set to + 1 in the Makefile.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. This + option will be silently ignored and will not appear + in the help message nor in the manual page if + SUPERUSER was set to + 0 in the Makefile.

    + +
    -l log +
    +

    Specify an alternate log file instead of the + default specified by LOGFILE in the + Makefile. No logging is performed if + the -n option is used.

    + +

    Log entries have the form:

    + +
    +    878790215   1.10+   I    /usr/local/pkgs/cpio-2.4.2            /usr/local
    +    878888916   2.1     I    /usr/local/pkgs/gzip-1.2.4            /usr/local
    +    878888916   2.1     IC   /usr/local/pkgs/gzip-1.2.4/bin/gzip   invalid symlink
    +
    + +

    This shows that a development version of + graft (1.10+) was used to install + symbolic links from /usr/local/pkgs/cpio-2.4.2 + to /usr/local. A new version of + graft (2.1) was used to install symbolic + links from /usr/local/pkgs/gzip-1.2.4 to + /usr/local. The IC entry indicates + that a conflict occurred during this + installation - the file /usr/local/pkgs/bin/gzip + was a symbolic link to something other than + /usr/local/pkgs/gzip-1.2.4/bin/gzip.

    + +
    -n +
    +

    List actions but do not perform them. Implies + the very verbose option. Does not require + superuser privileges regardless of the value of + SUPERUSER in the Makefile.

    + +
    -v +
    +

    Be verbose.

    + +
    -V +
    +

    Be very verbose.

    + +
    -r /rootdir +
    +

    Use the fully qualified named directory as the + root directory for all graft operations. The source + directory, target directory and log file will all + be relative to this specific directory.

    + +

    Can only be used by the superuser.

    + +
    -s +
    +

    Stow/Depot compatibility mode. + Infer the Graft target directory from + each package installation directory in the + manner of Stow and Depot.

    + +

    Target directory is the dirname of the + dirname of the package installation + directory. (Yes that really is two + dirnames). So if the package + installation directory is

    + +
    +    /usr/local/depot/gzip-1.2.4
    +
    + +

    the package will be grafted into +

    + +
    +    /usr/local
    +
    + +

    Cannot be used with the -t option.

    + +
    -t target +
    +

    Override the default graft target + directory with target. The value + of target must be a fully + qualified directory and it must exist.

    + +

    Cannot be used with the -s option.

    + +
    package +
    +

    Install the named package. If package is + a fully qualified directory, use it as the + package installation directory. If + package is not a fully qualified + directory, prepend it with the value of + PACKAGEDIR as specified in the + Makefile.

    + +
    + +
    + +
  2. Delete

    + +
    +    graft -d [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    + +
    + +
    -d +
    +

    Delete symbolic links from the package target + directory to the package installation + directory. Requires superuser privileges if + SUPERUSER was set to 1 in the + Makefile.

    + +
    -D +
    +

    Delete empty directories if + DELETEOBJECTS was set to 0 in the + Makefile. If the option is not + provided on the command line, notify the user + that a directory has been emptied.

    + +

    Do not delete empty directories if + DELETEOBJECTS was set to 1 in the + Makefile. Notify the user that a + directory has been emptied. If the option is + not provided on the command line, delete empty + directories.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile.

    + +
    -u +
    +

    Superuser privileges are not required when + deleting packages.

    + +

    This option is only available if + SUPERUSER was set to + 1 in the Makefile.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. This + option will be silently ignored and will not appear + in the help message nor in the manual page if + SUPERUSER was set to + 0 in the Makefile.

    + +
    -l log +
    +

    Specify an alternate log file instead of the + default specified by LOGFILE in the + Makefile. No logging is performed if + the -n option is used.

    + +

    Log entries have the form:

    + +
    +    879126278       1.10+   D       /usr/local/pkgs/weblint-1.017     /usr/local
    +    879126278       1.10+   DC      /usr/local/pkgs/weblint-1.017/bin/weblint  file exists
    +    879126278       1.10+   DC      /usr/local/pkgs/weblint-1.017/man/man1/weblint.1  file exists
    +
    + +

    This shows that a development version of + graft (1.10+) was used to delete + symbolic links from /usr/local to + /usr/local/pkgs/weblint-1.017. The DC + entries indicate that conflicts occurred during + this action - the files + /usr/local/bin/weblint and + /usr/local/man/man1/weblint.1 already + exist.

    + +
    -n +
    +

    List actions but do not perform them. Implies + the very verbose option. Does not require + superuser privileges regardless of the value of + SUPERUSER in the Makefile.

    + +
    -v +
    +

    Be verbose.

    + +
    -V +
    +

    Be very verbose.

    + +
    -r /rootdir +
    +

    Use the fully qualified named directory as the + root directory for all graft operations. The source + directory, target directory and log file will all + be relative to this specific directory.

    + +

    Can only be used by the superuser.

    + +
    -s +
    +

    Stow/Depot compatibility mode. + Infer the Graft target directory from + each package installation directory in the + manner of Stow and Depot.

    + +

    Target directory is the dirname of the + dirname of the package installation + directory. (Yes that really is two + dirnames). So if the package + installation directory is

    + +
    +    /usr/local/depot/gzip-1.2.4
    +
    + +

    the package will be grafted into +

    + +
    +    /usr/local
    +
    + +

    Cannot be used with the -t option.

    + +
    -t target +
    +

    Override the default graft target + directory with target. The value + of target must be a fully + qualified directory and it must exist.

    + +

    Cannot be used with the -s option.

    + +
    package +
    +

    Delete the named package. If package is + a fully qualified directory, use it as the + package installation directory. If + package is not a fully qualified + directory, prepend it with the value of + PACKAGEDIR as specified in the + Makefile.

    + +
    + +
    + +
  3. Prune

    + +
    +    graft -p [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
    +
    + +
    + +
    -p +
    +

    Prune objects (files, links or directories) + from the package target directory that are in + conflict with the package installation + directory. Requires superuser privileges if + SUPERUSER was set to 1 in the + Makefile.

    + +
    -D +
    +

    Remove conflicting objects if + DELETEOBJECTS was set to 0 in the + Makefile. Rename conflicting objects + as object.pruned if the option + is not provided on the command line.

    + +

    Rename conflicting objects to + object.pruned if + DELETEOBJECTS was set to 1 in the + Makefile. Remove conflicting objects + if the option is not provided in the command + line.

    + +

    If a directory is to be removed and it is not + empty, it will be renamed as + dir.pruned and a suitable + warning message will be given regardless of the + sense of this flag.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile.

    + +
    -u +
    +

    Superuser privileges are not required when + pruning packages.

    + +

    This option is only available if + SUPERUSER was set to + 1 in the Makefile.

    + +

    The Graft manual page will correctly + reflect the behaviour of this option based on the + values specified in the Makefile. This + option will be silently ignored and will not appear + in the help message nor in the manual page if + SUPERUSER was set to + 0 in the Makefile.

    + +
    -l log +
    +

    Specify an alternate log file instead of the + default specified by LOGFILE in the + Makefile. No logging is performed if + the -n option is used.

    + +

    Log entries have the form:

    + +
    +    879126283       1.10+   P       /usr/local/pkgs/weblint-1.017     /usr/local
    +
    + +

    This shows that a development version of + graft (1.10+) was used to delete objects + from /usr/local that were in conflict with + /usr/local/pkgs/weblint-1.017.

    + +
    -n +
    +

    List actions but do not perform them. Implies + the very verbose option. Does not require + superuser privileges regardless of the value of + SUPERUSER in the Makefile.

    + +
    -v +
    +

    Be verbose.

    + +
    -V +
    +

    Be very verbose.

    + +
    -r /rootdir +
    +

    Use the fully qualified named directory as the + root directory for all graft operations. The source + directory, target directory and log file will all + be relative to this specific directory.

    + +

    Can only be used by the superuser.

    + +
    -s +
    +

    Stow/Depot compatibility mode. + Infer the Graft target directory from + each package installation directory in the + manner of Stow and Depot.

    + +

    Target directory is the dirname of the + dirname of the package installation + directory. (Yes that really is two + dirnames). So if the package + installation directory is

    + +
    +    /usr/local/depot/gzip-1.2.4
    +
    + +

    the package will be grafted into +

    + +
    +    /usr/local
    +
    + +

    Cannot be used with the -t option.

    + +
    -t target +
    +

    Override the default graft target + directory with target. The value + of target must be a fully + qualified directory and it must exist.

    + +

    Cannot be used with the -s option.

    + +
    package +
    +

    Prune the named package. If package is + a fully qualified directory, use it as the + package installation directory. If + package is not a fully qualified + directory, prepend it with the value of + PACKAGEDIR as specified in the + Makefile.

    + +
    + +
  4. Information

    + +
    +    graft -L
    +
    + +
    + +
    -L +
    +

    This is a special mode and it overrides all + other command line arguments. When present + graft will display the + default locations for Perl, the + graft log file, the target directory, and the + package directory in a form suitable for creating + environment variables for Bourne like shells. The + output will appear on STDOUT as + follows:

    + +
    +    GRAFT_PERL=/usr/bin/perl
    +    GRAFT_LOGFILE=/var/log/graft
    +    GRAFT_TARGETDIR=/usr/local
    +    GRAFT_PACKAGEDIR=/usr/local/pkgs
    +
    + +

    You can set these environment variables using + one of the following methods.

    + +
    +    eval "$(graft -L)"    # modern shells such as bash, zsh etc
    +    eval "`graft -L`"     # older shells such as sh etc
    +
    + +
    + +
+ +
+ +

Testing the Graft Installation

+ +

Before creating the symbolic links from the target directory to +the package directory, you may wish to see what actions Graft +will perform. Execute the following command:

+ +
+    graft -i -n package-name
+
+ +

The -i option tells Graft to install the package and +the -n option tells Graft to report on its actions +without actually performing them. The default Graft target +directory will be used and the package installation directory will be +taken from the fully qualified package argument or the default value +will be prepended to the package argument if it is not fully qualified. +

+ +

Graft will report on the following actions:

+ + + +

If you were to test the installation of the kermit-5A190 +package you would execute the command:

+ +
+    graft -i -n kermit-5A190
+
+ +You should see output resembling: + +
+    Installing   links to /usr/local/pkgs/kermit-5A190 in /usr/local
+    Processing   /usr/local/pkgs/kermit-5A190
+    SYMLINK      /usr/local/README -> /usr/local/pkgs/kermit-5A190/README
+    NOP          /usr/local/pkgs/kermit-5A190/bin and /usr/local/bin are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    SYMLINK      /usr/local/bin/kermit -> /usr/local/pkgs/kermit-5A190/bin/kermit
+    SYMLINK      /usr/local/bin/wart -> /usr/local/pkgs/kermit-5A190/bin/wart
+    NOP          /usr/local/pkgs/kermit-5A190/man and /usr/local/man are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    NOP          /usr/local/pkgs/kermit-5A190/man/man1 and /usr/local/man/man1 are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    SYMLINK      /usr/local/man/man1/kermit.1 -> /usr/local/pkgs/kermit-5A190/man/man1/kermit.1
+    MKDIR        /usr/local/doc
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    SYMLINK      /usr/local/doc/ckccfg.doc -> /usr/local/pkgs/kermit-5A190/doc/ckccfg.doc
+    SYMLINK      /usr/local/doc/ckuins.doc -> /usr/local/pkgs/kermit-5A190/doc/ckuins.doc
+    SYMLINK      /usr/local/doc/ckc190.upd -> /usr/local/pkgs/kermit-5A190/doc/ckc190.upd
+    SYMLINK      /usr/local/doc/ckcker.upd -> /usr/local/pkgs/kermit-5A190/doc/ckcker.upd
+    SYMLINK      /usr/local/doc/ckaaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckaaaa.hlp
+    SYMLINK      /usr/local/doc/ckuaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckuaaa.hlp
+    NOP          /usr/local/pkgs/kermit-5A190/lib and /usr/local/lib are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    SYMLINK      /usr/local/lib/ckedemo.ini -> /usr/local/pkgs/kermit-5A190/lib/ckedemo.ini
+    SYMLINK      /usr/local/lib/ckeracu.ini -> /usr/local/pkgs/kermit-5A190/lib/ckeracu.ini
+    SYMLINK      /usr/local/lib/ckermit.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermit.ini
+    SYMLINK      /usr/local/lib/ckermod.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermod.ini
+    SYMLINK      /usr/local/lib/cketest.ini -> /usr/local/pkgs/kermit-5A190/lib/cketest.ini
+    SYMLINK      /usr/local/lib/ckevt.ini -> /usr/local/pkgs/kermit-5A190/lib/ckevt.ini
+    SYMLINK      /usr/local/lib/ckurzsz.ini -> /usr/local/pkgs/kermit-5A190/lib/ckurzsz.ini
+
+ +

This output shows you that most of the directories already exist +(indicated by the NOP flags). A symbolic link will be created +in the relevant target directory to each of the files in the +kermit-5A190 package. One directory exists in the +kermit-5A190 package that does not exist in the target - +doc. This directory will be created by Graft.

+ +

NOTE: If you are using the automounter you may not be +able to create the directory /usr/local/doc. You'll have to create +the directory on the NFS server under the file system in which it +really lives. You should be familiar with the peculiarities of the +automounter and your specific site configuration before creating +any directories directly under mount points used by the +automounter.

+ +
+ +

Installing Packages

+ +

Once you have ensured that Graft will perform the correct +actions, you can execute:

+ +
+    graft -i package-name
+
+ +

So to install kermit you would execute:

+ +
+    graft -i kermit-5A190
+
+ +

There will be no output from Graft unless it encounters a +conflict. If you wish to see more information you can specify one of +the verbose flags. For a minimum of output you can execute:

+ +
+    graft -i -v kermit-5A190
+
+ +

You should see the following output:

+ +
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+
+ +

If you choose the very verbose option by executing:

+ +
+    graft -i -V kermit-5A190
+
+ +

the output will be the same as that when the -n option was +used, however this time Graft will actually create the symbolic +links.

+ +
+    Installing   links to /usr/local/pkgs/kermit-5A190 in /usr/local
+    Processing   /usr/local/pkgs/kermit-5A190
+    SYMLINK      /usr/local/README -> /usr/local/pkgs/kermit-5A190/README
+    NOP          /usr/local/pkgs/kermit-5A190/bin and /usr/local/bin are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    SYMLINK      /usr/local/bin/kermit -> /usr/local/pkgs/kermit-5A190/bin/kermit
+    SYMLINK      /usr/local/bin/wart -> /usr/local/pkgs/kermit-5A190/bin/wart
+    NOP          /usr/local/pkgs/kermit-5A190/man and /usr/local/man are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    NOP          /usr/local/pkgs/kermit-5A190/man/man1 and /usr/local/man/man1 are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    SYMLINK      /usr/local/man/man1/kermit.1 -> /usr/local/pkgs/kermit-5A190/man/man1/kermit.1
+    NOP          /usr/local/pkgs/kermit-5A190/doc and /usr/local/doc are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    SYMLINK      /usr/local/doc/ckccfg.doc -> /usr/local/pkgs/kermit-5A190/doc/ckccfg.doc
+    SYMLINK      /usr/local/doc/ckuins.doc -> /usr/local/pkgs/kermit-5A190/doc/ckuins.doc
+    SYMLINK      /usr/local/doc/ckc190.upd -> /usr/local/pkgs/kermit-5A190/doc/ckc190.upd
+    SYMLINK      /usr/local/doc/ckcker.upd -> /usr/local/pkgs/kermit-5A190/doc/ckcker.upd
+    SYMLINK      /usr/local/doc/ckaaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckaaaa.hlp
+    SYMLINK      /usr/local/doc/ckuaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckuaaa.hlp
+    NOP          /usr/local/pkgs/kermit-5A190/lib and /usr/local/lib are both directories
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    SYMLINK      /usr/local/lib/ckedemo.ini -> /usr/local/pkgs/kermit-5A190/lib/ckedemo.ini
+    SYMLINK      /usr/local/lib/ckeracu.ini -> /usr/local/pkgs/kermit-5A190/lib/ckeracu.ini
+    SYMLINK      /usr/local/lib/ckermit.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermit.ini
+    SYMLINK      /usr/local/lib/ckermod.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermod.ini
+    SYMLINK      /usr/local/lib/cketest.ini -> /usr/local/pkgs/kermit-5A190/lib/cketest.ini
+    SYMLINK      /usr/local/lib/ckevt.ini -> /usr/local/pkgs/kermit-5A190/lib/ckevt.ini
+    SYMLINK      /usr/local/lib/ckurzsz.ini -> /usr/local/pkgs/kermit-5A190/lib/ckurzsz.ini
+
+ +

NOTE: In this case the /usr/local/doc directory was not +created by Graft because /usr/local is a mount point +controlled by the automounter. The doc directory was +created manually prior to executing Graft.

+ +
+ +

Bypassing package directories

+ +

You may have the need to place only part of a package under the control +of Graft. Examples of such occasions may be:

+ + + +

You can force Graft to bypass a directory by creating the file

+ +
+    package-name/dir/dir/.nograft
+
+ +

Using the second example above, if you were to create the file:

+ +
+    /usr/local/pkgs/perl-5.18.2/lib/perl5/.nograft
+
+ +

Graft would create directories and symbolic links for every file +and directory down to /usr/local/pkgs/perl-5.18.2/lib. The perl5 +directory and anything below it would not be created.

+ +
+ +

Including specific files and/or directories

+ +

There may be the occasional need to include specific files and/or +directories in a directory, rather than the entire directory tree itself. An +example of such an occurrence would be the case where a package +contains a number of subdirectories, only one of which is required to +be grafted.

+ +

You can force Graft to only include any number of files and/or +directories in a package directory by creating the file

+ +
+    .graft-include
+
+ +

in the same directory.

+ +

.graft-include will contain a list of file and/or directory names +- one per line - of the files and/or directories you wish to include.

+ +

Consider the a2ps package for example. When installed it +contains the following directories:

+ +
+    /usr/local/pkgs/a2ps-4.13b/bin
+    /usr/local/pkgs/a2ps-4.13b/etc
+    /usr/local/pkgs/a2ps-4.13b/include
+    /usr/local/pkgs/a2ps-4.13b/info
+    /usr/local/pkgs/a2ps-4.13b/lib
+    /usr/local/pkgs/a2ps-4.13b/man
+    /usr/local/pkgs/a2ps-4.13b/share
+
+ +

The only directory you wish to graft is the bin +directory. You could place a .nograft file in each of the other +directories, OR you could create a single .graft-include +file in /usr/local/pkgs/a2ps-4.13b/.graft-include. This file would +contain

+ +
+    bin
+
+ +

Now only the bin directory will be grafted.

+ +
+ +

Excluding specific files and/or directories

+ +

There may be the occasional need to exclude specific files and/or +directories from a directory, rather than the entire directory itself. An +example of such an occurrence would be the case where files from different +packages have the same name. Emacs and Xemacs use the same +names for a number of their configuration files for example.

+ +

You can force Graft to exclude any number of files and/or +directories from a package directory by creating the file

+ +
+    .graft-exclude
+
+ +

in the same directory.

+ +

.graft-exclude will contain a list of file and/or directory names +- one per line - of the files and/or directories you wish to exclude.

+ +

For example, if you did not wish the file

+ +
+    /usr/local/pkgs/sudo-1.5.3/etc/sudoers
+
+ +

to be grafted as

+ +
+    /usr/local/etc/sudoers
+
+ +

but you did want

+ +
+    /usr/local/pkgs/sudo-1.5.3/etc/visudo
+
+ +

to be grafted as

+ +
+    /usr/local/etc/visudo
+
+ +

you would create the file

+ +
+    /usr/local/pkgs/sudo-1.5.3/etc/.graft-exclude
+
+ +

and ensure its contents contained the line:

+ +
+    sudoers
+
+ +

NOTE: Any entries made in a .graft-exclude file will +override the same entries made in a .graft-include file. That is, +if a file or directory name is listen in both a .graft-exclude +and a .graft-include file, it will be excluded from the +graft.

+ +
+ +

Grafting configuration files

+ +

Beginning with Graft 2.11 there is now the ability to treat a +package directory as a repository for configuration files. In this case you +would place a .graft-config file in the package directory and any +files in that directory would be copied to the target +directory. Files in conflict would also be copied but would have a default +suffix of .new to ensure the existing file is not clobbered. +Conflict discovery is achieved using a simple 32-bit CRC check. This +feature has been added to assist operating system distributors manage +system configuration files, specifically it was added at the request of the +maintainer of the Dragora GNU/Linux +distribution.

+ +

Consider the following example. You may wish to upgrade the +openssh server as part of an upgrade to your distribution. In +order to preserve any local user modifications to the relevant +configuration files you would add a .graft-config file to the +package as follows:

+ +
+    /usr/local/pkgs/openssh-server-6.61/etc/default/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/init.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/init/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/network/if-up.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/pam.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/etc/ufw/applications.d/.graft-config
+    /usr/local/pkgs/openssh-server-6.61/lib/systemd/system/.graft-config
+
+ +

The other directories in the distribution would not require any control +files.

+ +

Imagine that the local administrator has made some changes to +/etc/pam.d/sshd such as adding additional authentication methods +to support two-factor authentication for example. As the distribution +maintainer you do not want to reverse this local change so when the local +administrator upgrades the distribution, Graft +copies the new /etc/pam.d/sshd file to +/etc/pam.d/sshd.new which allows the local administrator to merge +their changes with any new features supported by the upgrade.

+ +

To take full advantage of this feature you may need to explicitly set the +target directory as follows:

+ +
+    graft -i -t / openssh-server-6.61
+
+ +
+ +

Grafting part of a package

+ +

Some packages can be successfully used when only part of their +installation directory is grafted. Other packages are +recalcitrant and need some special hand holding which can only be +solved by grafting each section of the package separately.

+ +

The first scenario can be handled by either .nograft files or +partial grafts. Consider Perl version 5.18.2. +When installed in its own directory

+ +
+    /usr/local/pkgs/perl-5.18.2
+
+ +

there are three subdirectories

+ +
+    drwxr-sr-x   2 psamuel  bisg         512 Oct 30  1996 bin
+    drwxr-sr-x   3 psamuel  bisg         512 Oct 30  1996 lib
+    drwxr-sr-x   4 psamuel  bisg         512 Oct 30  1996 man
+
+ +

Everything in the lib directory is exclusive to Perl +and does not require grafting. Therefore, perl-5.18.2 can +be grafted using either of the following two methods:

+ +
+    touch /usr/local/pkgs/perl-5.18.2/lib/.nograft
+    graft -i perl-5.18.2
+
+ +or + +
+    graft -it /usr/local/bin perl-5.18.2/bin
+    graft -it /usr/local/man perl-5.18.2/man
+
+ +

Now let's consider a recalcitrant package - ObjectStore version +4.0.2.a.0. When installed in

+ +
+    /usr/local/pkgs/ostore-4.0.2.a.0
+
+ +

the following files and directories are available:

+ +
+    -rwxrwxr-x   1 pauln    one3        1089 Oct 31  1996 Copyright
+    drwxrwxrwx   8 pauln    one3         512 Oct  2  1996 common
+    drwxrwxrwx   6 pauln    one3         512 Oct 31  1996 sunpro
+    -rw-r-----   1 root     one3     1900544 Apr 29  1997 txn.log
+
+ +

The executable programs that need to be grafted are in +sunpro/bin and the manual pages that need to be grafted +are in common/man. Everything else in the package does not +need to be grafted. If the entire package was to be +grafted the result would be two directories that are not in the +regular $PATH and $MANPATH environment variables - namely +/usr/local/common/man and /usr/local/sunpro/bin, plus a host of +other directories that are not relevant for grafting. No amount +of .nograft and .graft-exclude juggling will solve +this problem.

+ +

The solution is to use two partial grafts:

+ +
+    graft -it /usr/local/bin ostore-4.0.2.a.0/sunpro/bin
+    graft -it /usr/local/man ostore-4.0.2.a.0/common/bin
+
+ +

Using this approach, the correct executables and manual pages are +available without the need to graft unnecessary files and +directories.

+ +
+ +

Deleting and/or Upgrading +Packages

+ +

If you wish to upgrade a package - let's assume you wish to upgrade +kermit from version 5A190 to version 6.0.192 - you'd follow +these steps.

+ +

Firstly, you'd compile and install kermit-6.0.192 in

+ +
+    /usr/local/pkgs/kermit-6.0.192
+
+ +

Once you'd tested it to your satisfaction, you'd need to delete the +symbolic links to the current grafted version. You can check +which actions Graft will perform by executing:

+ +
+    graft -d -n kermit-5A190
+
+ +

You'll see output similar to

+ +
+    Uninstalling links from /usr/local to /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    UNLINK       /usr/local/bin/kermit
+    UNLINK       /usr/local/bin/wart
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    UNLINK       /usr/local/man/man1/kermit.1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    UNLINK       /usr/local/doc/ckccfg.doc
+    UNLINK       /usr/local/doc/ckuins.doc
+    UNLINK       /usr/local/doc/ckc190.upd
+    UNLINK       /usr/local/doc/ckcker.upd
+    UNLINK       /usr/local/doc/ckaaaa.hlp
+    UNLINK       /usr/local/doc/ckuaaa.hlp
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    UNLINK       /usr/local/lib/ckedemo.ini
+    UNLINK       /usr/local/lib/ckeracu.ini
+    UNLINK       /usr/local/lib/ckermit.ini
+    UNLINK       /usr/local/lib/ckermod.ini
+    UNLINK       /usr/local/lib/cketest.ini
+    UNLINK       /usr/local/lib/ckevt.ini
+    UNLINK       /usr/local/lib/ckurzsz.ini
+    UNLINK       /usr/local/lib/.testing
+
+ +

If you're happy with the output from the test deletion you can delete +the grafted package. Once again, you'll only see output if a +failure occurs unless you use one of the verbose options.

+ +

If you execute:

+ +
+    graft -dV kermit-5A190
+
+ +

you'll see:

+ +
+    Uninstalling links from /usr/local to /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190
+    Processing   /usr/local/pkgs/kermit-5A190/bin
+    UNLINK       /usr/local/bin/kermit
+    UNLINK       /usr/local/bin/wart
+    Processing   /usr/local/pkgs/kermit-5A190/man
+    Processing   /usr/local/pkgs/kermit-5A190/man/man1
+    UNLINK       /usr/local/man/man1/kermit.1
+    Processing   /usr/local/pkgs/kermit-5A190/doc
+    UNLINK       /usr/local/doc/ckccfg.doc
+    UNLINK       /usr/local/doc/ckuins.doc
+    UNLINK       /usr/local/doc/ckc190.upd
+    UNLINK       /usr/local/doc/ckcker.upd
+    UNLINK       /usr/local/doc/ckaaaa.hlp
+    UNLINK       /usr/local/doc/ckuaaa.hlp
+    EMPTY        /usr/local/doc is now empty. Delete manually if necessary.
+    Processing   /usr/local/pkgs/kermit-5A190/lib
+    UNLINK       /usr/local/lib/ckedemo.ini
+    UNLINK       /usr/local/lib/ckeracu.ini
+    UNLINK       /usr/local/lib/ckermit.ini
+    UNLINK       /usr/local/lib/ckermod.ini
+    UNLINK       /usr/local/lib/cketest.ini
+    UNLINK       /usr/local/lib/ckevt.ini
+    UNLINK       /usr/local/lib/ckurzsz.ini
+
+ +

NOTE: In this case the existence of an empty directory has been +discovered. If Graft empties a directory during a package +deletion, it will either notify you or delete the directory depending +on the combination of variables in the Makefile and command +line options. It's probably better practise not to automatically +delete empty directories as they may be used by other packages - such +as lock file directories for example.

+ +

Now you can remove the real package contents. (You may not wish +to do this immediately as some legacy systems may depend on features +provided by the older version or you may feel the need for further +testing before feeling confident that the old version can be removed): +

+ +
+    rm -rf /usr/local/pkgs/kermit-5A190
+
+ +

Now you can graft the new version of kermit. Execute:

+ +
+    graft -i -n kermit-6.0.192
+
+ +

to ensure that the grafting will proceed without error. Once +you are satisfied that this is the case you can graft the new +package by executing:

+ +
+    graft -i kermit-6.0.192
+
+ +
+ +

Transitioning a package to Graft +control

+ +

Graft can be used to easily transition a package from its +current installation in your target directory to a grafted +installation.

+ +

As an example, let's consider the package weblint version 1.017. +It consists of three files installed in:

+ +
+    /usr/local/bin/weblint
+    /usr/local/lib/global.weblintrc
+    /usr/local/man/man1/weblint.1
+
+ +

The first step is to create a new copy of the package in its own +directory:

+ +
+    /usr/local/pkgs/weblint-1.017
+
+ +

Ensure that any references to library files are now made to +/usr/local/pkgs/weblint-1.017/lib instead of /usr/local/lib. +

+ +

Test the new installation to ensure it behaves as expected.

+ +

Then prune the old files from /usr/local/* using:

+ +
+    graft -pV weblint-1.017
+
+ +

You'd expect to see output similar to:

+ +
+    Pruning      files in /usr/local which conflict with /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017/man
+    Processing   /usr/local/pkgs/weblint-1.017/man/man1
+    RENAME       /usr/local/man/man1/weblint.1
+    Processing   /usr/local/pkgs/weblint-1.017/bin
+    RENAME       /usr/local/bin/weblint
+    Processing   /usr/local/pkgs/weblint-1.017/lib
+    RENAME       /usr/local/lib/global.weblintrc
+
+ +

If you elected to delete conflicting files instead of renaming them +you'd use:

+ +
+    graft -pDV weblint-1.017
+
+ +

and you'd see output similar to:

+ +
+    Pruning      files in /usr/local which conflict with /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017
+    Processing   /usr/local/pkgs/weblint-1.017/man
+    Processing   /usr/local/pkgs/weblint-1.017/man/man1
+    UNLINK       /usr/local/man/man1/weblint.1
+    Processing   /usr/local/pkgs/weblint-1.017/bin
+    UNLINK       /usr/local/bin/weblint
+    Processing   /usr/local/pkgs/weblint-1.017/lib
+    UNLINK       /usr/local/lib/global.weblintrc
+
+ +

Now the new version of weblint 1.017 can be grafted in +place:

+ +
+    graft -i weblint-1.017
+
+ +

The grafted version of weblint can now be tested.

+ +

If we renamed conflicting files, they can be removed once the +grafted weblint has been satisfactorily tested:

+ +
+    rm /usr/local/man/man1/weblint.1.pruned
+    rm /usr/local/bin/weblint.pruned
+    rm /usr/local/lib/global.weblintrc.pruned
+
+ +
+ +

Conflict Processing

+ +

Occasionally Graft will fail to completely install a package. This +occurs because Graft encounters a conflict. A conflict is defined as +one of the following possibilities:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Package Object + + Target Object +
+ directory + + not a directory +
+ file + + directory +
+ file + + file +
+ file + + symbolic link to something other than the package object +
+
+ +

If Graft encounters such a conflict during the installation of a +package it will report the conflict and exit.

+ +

Resolving the conflict depends on the nature of the conflict and is +beyond the scope of this discussion - however most conflicts will +either be the result of attempting to graft a package on top of +the same package actually installed in the target directory or a file +name clash between two (or more) different packages.

+ +

Conflicts arising from the pre-existence of a package in the target +directory can be resolved using graft's prune mechanism +described above in "Transitioning a +package to Graft control".

+ +

File name clash conflicts can be resolved by the use of either a +.nograft or +.graft-exclude file or by +grafting only part of a package as described above in +"Grafting part of a package". +

+ +

If Graft encounters a conflict while deleting a package, it will +report the conflict and continue deleting the remainder of the package. +In this way Graft will delete as much of the package as +possible. Conflicts that arise during deletion will probably be the +result of an incorrectly installed package or the installation of other +components of the same package without the use of Graft.

+ +

Conflict messages are written to standard error. All other messages +are written to standard output. To quickly determine if a package will +have any conflicts when grafted, redirect standard output to +/dev/null

+ +
+    graft -i -n package > /dev/null
+
+ +

If you don't see any output then you can safely assume that there will +be no conflicts when grafting this package.

+ +

See the comprehensive table above describing how +conflicts are handled for more details.

+ +
+ +

Exit Status

+ +

Graft will terminate with an exit status of either 0, 1, 2, 3 or 4 +under the following conditions:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Exit Status + + Condition +
+
+ 0 +
+
+ All operations succeeded. +
+
+ 1 +
+
+ A conflict occurred during installation. +
+
+ 2 +
+
+ Command line syntax was incorrect. +
+
+ 3 +
+
+ One or more packages listed on the command line does not + exist. Other valid packages listed on the command line were + processed correctly. +
+
+ 4 +
+
+ The log file /var/log/graft could not be updated. Usually a + result of a permission error. Any other error condition will + override this condition. +
+
+ +
+ +

Using Graft with other package +management tools

+ +

Most Unix vendors have released their own package management tools with +their operating systems. Examples of this are Solaris 2.x with its +SVR4 Package Manager pkgadd, RedHat Linux with its +RedHat Package Manager rpm, Ubuntu Linux (and other Debian +Linux derivatives) with its dpkg system and HP-UX 10.x with +its swinstall suite. Graft has been designed as an adjunct +to these package managers rather than a competitor. The author has used +Graft successfully with all of the operating systems mentioned here. +

+ + + +
+ +

Availability

+ +

The latest version of Graft should always be available from:

+ +
+    http://peters.gormand.com.au/Home/tools/graft
+
+ +
+ +

License

+ +

Graft is licensed under the terms of the GNU General Public +License, Version 2, June 1991.

+ +

You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or download +it from the Free Software Foundation's web site:

+ +
+    http://www.gnu.org/copyleft/gpl.html
+    http://www.gnu.org/copyleft/gpl.txt
+
+ + +
+ + + + + + + diff --git a/website/manual/en/pkgmanagement.t2t b/website/manual/en/pkgmanagement.t2t new file mode 100644 index 00000000..e920763f --- /dev/null +++ b/website/manual/en/pkgmanagement.t2t @@ -0,0 +1,8 @@ + + + += Part IV - Package management = + +%!include(html): ''qi.html'' +%!include(html): ''graft.html'' + diff --git a/website/manual/en/qi.html b/website/manual/en/qi.html new file mode 100644 index 00000000..09df7d91 --- /dev/null +++ b/website/manual/en/qi.html @@ -0,0 +1,1406 @@ + + + + + +Qi user guide + + + + + + + + + + + + + + + + + +

Qi user guide

+ + + + + + +

Table of Contents

+ +
+ + +
+ + + +
+

+Next: , Up: (dir)   [Contents][Index]

+
+ + +

This user guide is for Qi (version 1.0, +15 April 2019). +

+ + + + + + + + + + + + + +
+

Copyright (C) 2019 Matias Fonzo. +

+

Qi’s home page can be found at http://www.dragora.org. +Send bug reports or suggestions to dragora-users@nongnu.org. +

+
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

1 Introduction

+ + +

Qi is a simple but well-integrated package manager. It can create, +install, remove, and upgrade software packages. Qi produces binary +packages using recipes, which are files containing specific instructions +to build each package from source. Qi can manage multiple packages +under a single directory hierarchy. This method allows to maintain a set +of packages and multiple versions of them. This means that Qi could be +used as the main package manager or complement the existing one. +

+

Qi offers a friendly command line interface, a global configuration +file, a simple recipe layout to deploy software packages; also works +with binary packages in parallel, speeding up installations and packages +in production. The format used for packages is a simplified but safe +POSIX pax archive compressed with lzip. +

+

Qi is a modern (POSIX-compliant) shell script released under the +terms of the GNU General Public License. There are only two major +dependencies for the magic: graft(1) and tarlz(1), the rest is expected +to be found in any Unix-like system. +

+
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

2 Invoking qi

+ + +

This chapter describes the synopsis and command line options for +invoke Qi. +

+
+
Usage: qi [OPTION]... [FILE]...
+
+ +

One mandatory option specifies the operation that ‘qi’ should +perform, other options are meant to detail how this operation should be +performed. +

+

qi supports the following options to operate: +

+
+
-b
+

Build package using recipe names. +

+
+
-c
+

Create .tlz package from directory. +

+
+
-d
+

Delete packages. +

+
+
-i
+

Install packages. +

+
+
-o
+

Resolve build order through .order files. +

+
+
-u
+

Update packages (implies -i, -d and -p options). +

+
+
-w
+

Warn about files that will be linked. +

+
+
-x
+

Extract a package for debugging purposes. +

+
+ +

There are common options between modes: +

+
+
-N
+

Do not read the configuration file. +

+

This will ignore any value in the qirc file. +

+
+
-P <DIR>
+

Package directory for installations. +

+

This option sets ‘${packagedir}’. +

+

Only valid for -i, -d, or -u options. +

+
+
-f
+

Force option. +

+

This option can force the build of a recipe, or force the update of a +pre-existing package. +

+

Only valid for -b, -u options. +

+
+
-t <DIR>
+

Target directory for symbolic links. +

+

This option sets ‘${targetdir}’. +

+

Only valid for -i, -d, or -u options. +

+
+
-k
+

Keep (don’t delete) ‘${srcdir}’ or ‘${destdir}’ in build +mode, keep (don’t delete) package directory in delete mode. +

+

Only valid for -b, -d or -u options. +

+
+
-p
+

Prune conflicts on package installations. +

+

This option may proceed with the package installation if one or more +conflicts occur. +

+
+
-r /rootdir
+

Use the fully qualified named directory as the root directory for all qi +operations. The target directory and package directory will be relative +to the specified directory, including the log file for graft. +

+
+
-v
+

Be verbose (a 2nd -v gives more). +

+
+ +

Options for build mode (-b): +

+
+
-O <DIR>
+

Where the packages produced are written. +

+

This option sets ‘${outdir}’. +

+
+
-W <DIR>
+

Where archives, patches, and recipes are expected. +

+

This option sets ‘${worktree}’. +

+
+
-Z <DIR>
+

Where (compressed) sources will be found. +

+

This option sets ‘${tardir}’. +

+
+
-a
+

Architecture to use. +

+

Default value is obtained via uname(1) as ‘uname -m’. +

+
+
-j
+

Parallel jobs for the compiler. +

+

If not specified, default sets to 1. +

+
+
-1
+

Increment release number (‘${release}’ + 1). +

+

It will be omitted if the -n option is being used. +

+
+
-n
+

Don’t create a .tlz package. +

+
+
-S
+

Selects the option to skip completed recipes. +

+

This means, in interactive mode, when the dialog +to summarize recipes is shown. +

+
+ +

Informative options: +

+
+
-L
+

Print default directory locations. +

+

This will print the target directory, package directory, working tree, +the directory for tarballs, and the output directory for the packages +produced. +

+
+
-h
+

Display the help describing the options and then exit. +

+
+
-V
+

Print the version number and license information. +The version number should be included in all bug reports. +

+
+ +

Expected non-option arguments are package directories and regular files: +recipes or files ending in .tlz, .order. When FILE is -, qi can read from +the standard input. See examples in Packages. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

3 The qirc file

+ + +

The global qirc file offers a way to define variables and tools +(such as a download manager) for default use. This file is used by qi +at runtime, e.g., to build, install, remove or upgrade packages. +

+

It has the following rules: +

+ + +

The command line options related to the package directory and target +directory plus some of the options used for the build mode can override +some values in qirc. See Invoking qi. +

+

The order in which qi looks for this file is: +

+
    +
  1. ${HOME}/.qirc + Effective user. + +
  2. ${sysconfdir}/qirc’ + System-wide. +
+ +

If you intend to run qi as effective user, the file +‘${sysconfdir}/qirc’ could be copied to ${HOME}/.qirc +setting the paths for ‘${packagedir}’ and ‘${targetdir}’ +according to the $HOME. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

4 Packages

+ + +

A package is a suite of programs usually distributed in binary form +which may also contain manual pages, documentation, or any other file +associated to a specific software. +

+

The package format used by qi is a simplified POSIX pax archive +compressed with lzip. The file extension for packages is ‘.tlz’. +

+

Both package installation and package de-installation are managed using +two important (internal) variables: ‘${packagedir}’ and +‘${targetdir}’, these values can be changed in the +configuration file or via options. +

+

${packagedir}’ is a common directory tree where the package +contents will be decompressed (will reside). +

+

${targetdir}’ is a target directory where the links will be +made by graft(1) taking ‘${packagedir}/package_name’ into account. +

+

Packages are installed in self-contained directory trees and symbolic +links from a common area are made to the package files. This allows +multiple versions of the same package to coexist on the same system. +

+ +

4.1 Package conflicts

+ + +

All the links to install or remove a package are handled by graft(1). +Since multiple packages can be installed or removed at the same time, +certain conflicts may arise between the packages. +

+

graft1 +defines a CONFLICT as one of the following conditions: +

+ + +

The default behavior of qi for an incoming package is to ABORT if a +conflict arises. When a package is going to be deleted, qi tells to +graft(1) to remove those parts that are not in conflict, leaving the +links to the belonging package. This behavior can be forced if the +-p option is given. +

+ +

4.2 Installing packages

+ + +

To install a single package, simply type: +

+
+
qi -i coreutils-8.30-i586+1.tlz
+
+ +

To install multiple packages at once, type: +

+
+
qi -i gcc-8.3.0-i586+1.tlz rafaela-2.2-i586+1.tlz ...
+
+ +

Warn about the files that will be linked: +

+
+
qi -w bash-5.0-i586+1.tlz
+
+ +

This is to verify the content of a package before installing it. +

+

See the process of an installation (very verbose): +

+
+
qi -i -v mariana-3.0-i586+1.tlz
+
+ +

A second -v gives more. +

+

Installing package in a different location: +

+
+
qi -r /media/floppy -i lzip-1.21-i586+1.tlz
+
+ +

The -r option assumes ‘${targetdir}’ and ‘${packagedir}’. +See: +

+
+
qi -r /home/selk -P /pkgs -t / -i lzip-1.21-i586+1.tlz
+
+ +

In this case the content of "lzip-1.21-i586+1.tlz" will be decompressed +into ‘/home/selk/pkgs/lzip-1.21-i586+1’. Assuming that the main +binary for lzip is under ‘/home/selk/pkgs/lzip-1.21-i586+1/usr/bin/’ +the target for "usr/bin" will be created at ‘/home/selk’. Considering +that you have exported the PATH as ‘${HOME}/usr/bin’, now the +system is able to see the recent lzip. +

+

Installing from a list of packages using standard input: +

+
+
cat FILELIST.txt | qi -i -
+
+ +

The list of packages must contain full path names to be passed in the +installation, e.g.: +/var/cache/qi/packages/x86_64/devel/tcl-8.6.9-x86_64+1.tlz +/var/cache/qi/packages/x86_64/devel/tk-8.6.9.1-x86_64+1.tlz +/var/cache/qi/packages/x86_64/devel/vala-0.42.3-x86_64+1.tlz +

+ +

4.3 Removing packages

+ + +

To remove a package, simply type: +

+
+
qi -d xz-5.2.4-i586+1.tlz
+
+ +

Delete mode will match the package name using ‘${packagedir}’ as +prefix. For example, if the value of ‘${packagedir}’ is set to +/usr/local/pkgs, this will be equal to: +

+
+
qi -d /usr/local/pkgs/xz-5.2.4-i586+1
+
+ +

Detailed output (very verbose): +

+
+
qi -d -v /usr/local/pkgs/xz-5.2.4-i586+1
+
+ +

A second -v gives more. +

+

By default the delete mode does not preserve a package directory after +removing its links from ‘${targetdir}’, but this behavior can be +changed if the -k option is passed: +

+
+
qi -d -k /usr/local/pkgs/lzip-1.21-i586+1
+
+ +

This means that the links to the package can be reactivated, later: +

+
+
cd /usr/local/pkgs && graft -i lzip-1.21-i586+1
+
+ +

Removing package from a different location: +

+
+
qi -r /home/cthulhu -P /pkgs -t / -d xz-5.2.4-i586+1
+
+ +

Removing a package using standard input: +

+
+
echo "vala-0.42.3-x86_64+1" | qi -d -
+
+ +

This will match with the package directory. +

+ +

4.4 Upgrading packages

+ + +

The upgrade mode inherits the properties of the installation and removal +process. To make sure that a package is updated, the package is installed +in a temporary directory taking ‘${packagedir}’ into account. Once +the incoming package is pre-installed, qi can proceed to search and delete +packages that have the same name (considered as previous ones). Finally, +the package is re-installed at its final location and the temporary +directory is removed. +

+

To upgrade a package, just type: +

+
+
qi -u gcc-9.0.1-i586+1.tlz
+
+ +

This will proceed to update "gcc-9.0.1-i586+1" removing other versions +of "gcc" (if any). +

+

If you want to keep the package directories of versions found during the +upgrade process, just pass: +

+
+
qi -u -k gcc-9.0.1-i586+1.tlz
+
+ +

To see the upgrade process (very verbose): +

+
+
qi -u -v gcc-9.0.1-i586+1.tlz
+
+ +

A second -v gives more. +

+

To force the upgrade of an existing package: +

+
+
qi -u -f gcc-9.0.1-i586+1.tlz
+
+ + +

4.4.1 Package blacklist

+ + +

To implement general package facilities, either to install, remove or +maintain the hierarchy of packages in a clean manner, qi makes use of the +pruning operation via graft(1): +

+

There is a risk if those are crucial packages for the proper functioning +of the system, because it implies the deactivation of symbolic from the +target directory, especially when transitioning an incoming package +into its final location during upgrade. +

+

A blacklist of package names has been devised for the case where +a user decides to upgrade all packages in the system, or +just the crucial ones, such as the C library. +

+

The blacklist is related to the upgrade mode only, consists in installing +a package instead of updating it or removing previous versions of it; +the content of the package will be updated over the existing content at +‘${packagedir}’, while the existing links from +‘${targetdir}’ will be preserved. A pruning of links will be +carried out in order to re-link possible differences with the recent +content, this helps to avoid leaving dead links in the target directory. +

+

Since the upgrade mode is also used to install a new package, the mechanism +for blacklist is to install a declared package if it does not already +exist. If it already exists, it is verified that the binary package is +newer than the package directory in order to perform an update. +

+

Package names for the blacklist can be set from the configuration file. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

5 Recipes

+ + +

A recipe is a file telling qi what to do. Most often, the recipe tells +qi how to build a binary package from a source tarball. +

+

A recipe has two parts: a list of variable definitions and a list of +sections. By convention, the syntax of a section is: +

+
+
section_name()
+{
+    section lines
+}
+
+ +

The section name is followed by parentheses, one newline and an opening +brace. The line finishing the section contains just a closing brace. +The section names or the function names currently recognized are +‘build’. +

+

The ‘build’ section is an augmented shell script. This is the main +section (or shell function) which contains the instructions to +build and produce a package. +

+ +

5.1 Variables

+ + +

A "variable" is a shell variable defined either in qirc +or in a recipe to represent a string of text, called the variable’s +"value". These values are substituted by explicit request in the +definitions of other variables or in calls to external commands. +

+

Variables can represent lists of file names, options to pass to +compilers, programs to run, directories to look in for source files, +directories to write output to, or anything else you can imagine. +

+

Definitions of variables in qi have four levels of precedence. +Options which define variables from the command-line override those +specified in the qirc file, while variables defined in the recipe +override those specified in qirc, taking priority over those +variables set by command-line options. Finally, the variables have +default values if they are not defined anywhere. +

+

Options that set variables through the command-line can only reference +variables defined in qirc and variables with default values. +

+

Definitions of variables in qirc can only reference variables +previously defined in qirc and variables with default values. +

+

Definitions of variables in the recipe can only reference variables +set by the command-line, variables previously defined in the recipe, +variables defined in qirc, and variables with default values. +

+ +

5.2 Special variables

+ + +

There are variables which can only be set using the command line options or +via qirc, there are other special variables which can be defined or +redefined in a recipe. See the following definitions: +

+

outdir’ is the directory where the packages produced are written. +This variable can not be redefined in the recipe. Default sets to +‘/var/cache/qi/packages’. +

+

worktree’ is the working tree where archives, patches, and recipes +are expected. This variable can not be redefined in the recipe. Default +sets to ‘/usr/src/qi’. +

+

tardir’ is defined in the recipe to the directory where the tarball +containing the source can be found. The full name of the tarball is +composed as ‘${tardir}/$tarname’. Its value is available in the +recipe as ‘${tardir}’; a value of . for ‘tardir’ sets it to +the value of CWD (Current Working Directory), this is where the recipe +lives. +

+

arch’ is the architecture to compose the package name. Its value is +available in the recipe as ‘${arch}’. Default value is the output +of ‘uname -m’. +

+

jobs’ is the number of parallel jobs to pass to the compiler. Its +value is available in the recipe as ‘${jobs}’. The default value +is 1. +

+

The two variables ‘${srcdir}’ and ‘${destdir}’ can be +set in the recipe, as any other variable, but if they are not, qi uses +default values for them when building a package. +

+

srcdir’ contains the source code to be compiled, and defaults to +‘${program}-${version}’. ‘destdir’ is the place where the +built package will be installed, and defaults to +‘${TMPDIR}/package-${program}’. +

+

If ‘pkgname’ is left undefined, the special variable ‘program’ +is assigned by default. If ‘pkgversion’ is left undefined, the +special variable ‘version’ is assigned by default. +

+

pkgname’ and ‘pkgversion’ along with: ‘version’, ‘arch’, +and ‘release’ are used to produce the name of the package in the form: +‘${pkgname}-${pkgversion}-${arch}+${release}.tlz’ +

+

A special variable called ‘replace’ can be used to declare package +names that will be replaced at the time of installation. +

+

A typical recipe contains the following variables: +

+ + +

Obtaining sources over the network must be declared in the recipe using +the ‘fetch’ variable. Use double quotes for separated values. +

+

The variables ‘netget’ and ‘rsync’ can be defined in qirc +to establish a network downloader in order to get the sources. If they +are not defined, qi uses default values: +

+

netget’ is the general network downloader tool, defaults sets to +‘wget -c -w1 -t3 --no-check-certificate’. +

+

rsync’ is the network tool for sources containing the prefix for +the RSYNC protocol, default sets to +‘rsync -v -a -L -z -i --progress’. +

+

The variable ‘description’ is used to print the package description +when a package is installed. +

+

A description has two parts: a brief description, and a long description. +By convention, the syntax of ‘description’ is: +

+
+
description="
+Brief description.
+
+Long description.
+"
+
+ +

The first line of the value represented is a brief description of the +software (called "blurb"). A blank line separates the brief +description from the long description, which should contain a more +descriptive description of the software. +

+

An example looks like: +

+
+
description="
+The GNU core utilities.
+
+The GNU core utilities are the basic file, shell and text manipulation
+utilities of the GNU operating system.  These are the core utilities
+which are expected to exist on every operating system.
+"
+
+ +

Please consider a length limit of 78 characters as maximum, because the same +one would be used on the meta file creation. See +The meta file section. +

+

The ‘homepage’ variable is used to declare the main site or home page: +

+
+
homepage=http://www.gnu.org/software/gcc
+
+ +

The variable ‘license’ is used for license information2. +Some code in the program can be covered by license A, license B, or +license C. For "separate licensing" or "heterogeneous licensing", we +suggest using | for a disjunction, & for a conjunction +(if that ever happens in a significant way), and comma for heterogeneous +licensing. Comma would have lower precedence, plus added special terms. +

+
+
license="LGPL, GPL | Artistic + added permission"
+
+ + +

5.3 Writing recipes

+ + +

Originally, qi was designed for the version 3 of Dragora GNU/Linux (this +does not mean that you can use it in another distribution). Therefore we +will put here some references where you will be able to find real and +complete examples to write good recipes: +

+

http://git.savannah.nongnu.org/cgit/dragora.git/tree/recipes. +http://notabug.org/dragora/dragora/src/master/recipes. +

+

You can also check the "doc" directory in the distribution sources of qi +for some examples. +

+ +

5.4 Building packages

+ + +

A recipe is any valid regular file. Qi sets priorities for reading a +recipe, the order in which qi looks for a recipe is: +

+
    +
  1. Current working directory. + +
  2. If the specified path name does not contain "recipe" as the last +component. Qi will complete it by adding "recipe" to the path name. + +
  3. If the recipe is not in the current working directory, it will be +searched under ‘${worktree}/recipes’. The last component will be +completed adding "recipe" to the specified path name. +
+ +

To build a single package, type: +

+
+
qi -b x-apps/xterm
+
+ +

Multiple jobs can be passed to the compiler to speed up the build process: +

+
+
qi -b -j3 x-apps/xterm
+
+ +

Update or install the package produced (if it is not already installed) +when finish: +

+
+
qi -b -j3 -u x-apps/xterm
+
+ +

Only process a recipe but do not create the binary package: +

+
+
qi -b -n dict/aspell
+
+ +

The options -i or -u have no effect when -n is given. +

+

This can be useful to inspect the build process of recipe: +

+

qi -b -k -n dict/aspell 2>&1 | tee aspell-buildlog.txt +

+

The -k option could preserve the source directory and the destination +directory for later inspection. A log file of the build process will be +created redirecting both, standard error and standard output to tee(1). +

+ +

5.5 Variables from the environment

+ + +

Qi has environment variables which can be used at build time: +

+

The variable TMPDIR sets the temporary directory for sources, which is +used for package extractions (see Examining packages) and is +prepended to the value of ‘${srcdir}’ and ‘${destdir}’ in +build mode. By convention its default value is equal to +‘/usr/src/qi/build’. +

+

The variables QICFLAGS, QICXXFLAGS, and QILDFLAGS have +no effect by default. The environment variables such as CFLAGS, +CXXFLAGS, and LDFLAGS are unset at compile time: +

+

Recommended practice is to set variables in the command line of +‘configure’ or make(1) instead of exporting to the +environment. As follows: +

+
+

Variables not defined in a site shell script can be set in the environment +passed to configure. However, some packages may run configure again +during the build, and the customized values of these variables may be +lost. In order to avoid this problem, you should set them in the +configure command line, using ‘VAR=value’. For example: +

+

./configure CC=/usr/local2/bin/gcc +

+

http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Defining-Variables.html +

+ +
+

Indeed, while configure can notice the definition of CC in +‘./configure CC=bizarre-cc’, it is impossible to notice it in +‘CC=bizarre-cc ./configure’, which, unfortunately, is what most +users do. +

+

[...] +

+

configure: error: changes in the environment can compromise the build. +

+

http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Setting-Output-Variables.html +

+ +
+

It is not wise for makefiles to depend for their functioning on +environment variables set up outside their control, since this would cause +different users to get different results from the same makefile. This is +against the whole purpose of most makefiles. +

+

http://gnu.org/software/make/manual/make.html#Environment +

+ + +

5.6 The meta file

+ + +

The "meta file" is a regular file created during the build mode, it +contains information about the package such as program name, program +version, release, fetch address, description, and other minor data +extracted from processed recipes. The name of the file is generated as +‘${full_pkgname}.tlz.txt’, and its purpose is to reflect essential +information to the user without having to look inside the package content. +

+

The content of a meta file looks like: +

+
+
#
+# The Bourne Again SHell.
+#
+# Bash is an sh-compatible shell that incorporates useful features from
+# the Korn shell (ksh) and C shell (csh).  It is intended to conform to
+# the IEEE POSIX P1003.2/ISO 9945.2 shell and tools standard.
+#
+# It offers functional improvements over sh for both programming and
+# interactive use.
+#
+
+QICFLAGS="-g0 -Os -mtune=generic -pipe"
+QICXXFLAGS="-g0 -Os -mtune=generic -pipe"
+QILDFLAGS="-s"
+program=bash
+version=5.0
+release=1
+blurb="The Bourne Again SHell."
+homepage="http://www.gnu.org/software/bash"
+license="GPLv3+"
+fetch="ftp://ftp.gnu.org/gnu/bash/bash-5.0.tar.gz"
+replace=""
+
+ +

Package descriptions are extracted from the variable ‘description’: +each line is interpreted literally and pre-formatted to fit in (exactly) +80 columns, plus the character ‘#’ and a space is prefixed +to every line. +

+

In addition to the Special variables, there are implicit variables such as +‘blurb’: +

+

The ‘blurb’ variable is related to the special variable +‘description’. Its value is composed using the first (substantial) +line of ‘description’, mentioned as the "brief description". +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

6 Order files

+ + +

The order mode has the purpose of resolving the build order through +.order files. An order file contains a list of recipe names, by default +does not perform any action other than to print a resolved list in +descending order. For example, if a depends on b and +c, and c depends on b as well, the file might +look like: +

+
+
a: c b
+b:
+c: b
+
+ +

Each letter represents a recipe name, complete dependencies for +the first recipe name are listed in descending order, which is +printed from right to left, and removed from left to right: +

+

OUTPUT +

+
+
b
+c
+a
+
+ +

Blank lines, colons and parentheses are simply ignored. Comment lines +beginning with ‘#’ are allowed. +

+

An order file could be used to build a series of packages, for example, +if the content is: +

+
+
# Image handling libraries
+
+libs/libjpeg-turbo: devel/nasm
+x-libs/jasper: libs/libjpeg-turbo
+libs/tiff: libs/libjpeg-turbo
+
+ +

To proceed with each recipe, we can type: +

+
+
qi -o imglibs.order | qi -b -i -
+
+ +

The output of ‘qi -o imglibs.order’ tells to qi in which order it +should build the recipes: +

+
+
devel/nasm
+libs/libjpeg-turbo
+x-libs/jasper
+libs/tiff
+
+ + +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

7 Creating packages

+ + +

The "creation mode" is an internal function of qi to make new Qi compatible +compatible packages, the creation mode is selected by the -c option. +A package is produced using the contents of the Current Directory, and +the package file is written out. +

+
+
Usage: qi -c [OUTPUT/packagename.tlz]...
+
+ +

The argument for the file name to be written must contain a fully +qualified named directory as the output directory where the package +produced will be written. The file name should be composed using the +full name: name-version-architecture+release.tlz +

+

EXAMPLE +

+
+
cd /usr/local/pkgs
+cd claws-mail-3.17.1-x86_64+1
+qi -c /var/cache/qi/packages/x86_64/local/claws-mail-3.17.1-x86_64+1.tlz
+
+ +

In this case, the package "claws-mail-3.17.1-x86_64+1.tlz" will be written +into ‘/var/cache/qi/packages/x86_64/local/’. +

+

All packages produced are complemented by a checksum file (.sha256). +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

8 Examining packages

+ + +

The "extraction mode" serves to examine binary packages for debugging +purposes. The extraction mode is selected by the -x option. It +decompresses a package into a single directory, verifying its integrity +and preserving its properties. +

+
+
Usage: qi -x [packagename.tlz]...
+
+ +

EXAMPLE +

+
+
qi -x mksh-R56c-x86_64+1.tlz
+
+ +

This action will put the content of "mksh-R56c-x86_64+1.tlz" into a +single directory, this will be a private directory for the user who +

+

requested the action, creation mode will be equal to u=rwx,g=,o= +(0700). The package content will reside on this location, default +mask to deploy the content will be equal to +u=rwx,g=rwx,o=rwx (0000). +

+

The creation of the custom directory is influenced by the value of the +TMPDIR variable. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

9 Exit status

+ + +

All the exit codes are described in this chapter. +

+
+
0
+

Successful completion (no errors). +

+
+
1
+

Minor common errors: +

+
    +
  • - Help usage on illegal options or required arguments. + +
  • - Program needed by qi (prerequisite) is not available. +
+ +
+
2
+

Command execution error: +

+

This code is used to return the evaluation of external commands and shell +arguments in case of error. +

+
+
3
+

Integrity check error for compressed files. +

+

Compressed files means: +

+
    +
  • - Tarball files from tar(1). +Supported extensions: .tar, .tar.gz, .tgz, .tar.Z, .tar.bz2, .tbz2, .tbz, +.tar.xz, .txz + +
  • - Tarball files from tarlz(1). +Supported extensions: .tar.lz, .tlz + +
  • - Zip files from unzip(1). +Supported extensions: .zip, .ZIP + +
  • - Gzip files from gzip(1). +Supported extensions: .gz, .Z + +
  • - Bzip2 files from bzip2(1). +Supported extensions: .bz2 + +
  • - Lzip files from lzip(1). +Supported extensions: .lz + +
  • - Xz files from xz(1). +Supported extensions: .xz +
+ +
+
4
+

File empty, not regular, or expected. +

+

Commonly, it is expected: +

+
    +
  • - An argument for the mode of operation. + +
  • - A readable file or directory. + +
  • - A binary package (.tlz). + +
  • - A valid recipe. + +
  • - An order file (.order). + +
  • - A protocol supported by the network downloader tool. + +
  • - A checksum file (.sha256). +
+ +
+
5
+

Empty or not defined variable: +

+

This code is used to report empty or undefined variables; usually, +variables coming from a recipe or assigned arrays that are tested. +

+
+
6
+

Package already installed: +

+

The package directory for an incoming .tlz package already exists. +

+
+
10
+

Network manager error: +

+

This code is used if the network downloader tool fails for some reason. +

+
+ + +
+ +
+

+Previous: , Up: Top   [Contents][Index]

+
+ +

Index

+ +
Jump to:   C +   +E +   +H +   +I +   +M +   +P +   +R +   +S +   +T +   +V +   +W +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

C
configuration file: The qirc file

E
environment variables: Recipes
exit codes: Exit status

H
handling build order: Order files

I
introduction: Introduction
invocation: Invoking qi

M
managing packages: Packages

P
package blacklist: Packages
package build: Recipes
package conflicts: Packages
package creation: Creating packages
package de-installation: Packages
package examination: Examining packages
package installation: Packages
package upgrade: Packages

R
recipes: Recipes

S
special variables: Recipes

T
the meta file: Recipes

V
variables: Recipes

W
writing recipes: Recipes

+
Jump to:   C +   +E +   +H +   +I +   +M +   +P +   +R +   +S +   +T +   +V +   +W +   +
+ +
+
+

Footnotes

+ +

(1)

+

The official guide for Graft can be found at +http://peters.gormand.com.au/Home/tools/graft/graft.html.

+

(2)

+

The proposal for ‘license’ was made by Richard M. Stallman at +http://lists.gnu.org/archive/html/gnu-linux-libre/2016-05/msg00003.html.

+
+
+ + + + + diff --git a/website/manual/index.html b/website/manual/index.html new file mode 100644 index 00000000..7318b8b5 --- /dev/null +++ b/website/manual/index.html @@ -0,0 +1,3 @@ + + + -- 2.11.4.GIT