ACS Documentation : ACS Core Architecture Guide : ACS Package Manager (APM)
The ACS itself a collection of interdependent library and application packages. Prior to ACS 3.3, all packages were lumped together into one monolithic distribution without explicit boundaries; the only way to ascertain what comprised a given package was to look at the top of the corresponding documentation page, where, by convention, the package developer would specify where to find:
Experience has shown us that this lack of explicit boundaries causes a number of maintainability problems for pre-3.3 installations:
This last point is especially important. In most cases, changing the data model should not affect dependent packages. Rather, the package interface should provide a level of abstraction above the data model (as well as the rest of the package implementation). Then, users of the package can take advantage of implementation improvements that don't affect the interface (e.g., faster performance from intelligent denormalization of the data model), without having to worry that code outside the package will now break.
dpkg
and Apt
Borrowing from all of the above, ACS 3.3 introduces its own package management system, the ACS Package Manager (APM), which consists of:
For a simple illustration of the difference between ACS without APM (pre-3.3) and ACS with APM (3.3 and beyond), consider a hypothetical ACS installation that uses only two of the thirty-odd modules available circa ACS 3.2 (say, bboard and ecommerce):
APM itself is part of a package, ACS Core, a library package that is the only mandatory component of an ACS installation.
/user-search
.info
fileHere is a sample excerpt from the specification of the ACS Core package itself:
The only attributes of the<?xml version="1.0"?> <!-- Generated by the ACS Package Manager --> <package key="acs-core" url="http://software.arsdigita.com/packages/acs-core"> <version name="3.3.0" url="http://software.arsdigita.com/packages/acs-core-3.3.0.apm"> <package-name>ACS Core</package-name> <owner url="mailto:jsalz@mit.edu">Jon Salz</owner> <summary>Routines and data models providing the foundation for ACS-based Web services.</summary> <release-date>2000-06-03</release-date> <vendor url="http://www.arsdigita.com/">ArsDigita Corporation</vendor> <provides url="http://software.arsdigita.com/packages/developer-support/tcl-api" version="0.2d"/> <!-- No included packages --> <files> <file type="tcl_procs" path="00-proc-procs.tcl"/> <file type="tcl_procs" path="10-database-procs.tcl"/> ... </files> </version> </package>
<package>
element itself are
key
and url
. The key
attribute
is a default short name for the package that appears in the APM site
administrator UI; to enable the prevention of namespace collision, the
key
is not fixed but can be changed within an ACS
installation. The url
attribute identifies the
authoritative distribution point for the package (specifically, a
directory from which all versions of the package can be obtained). It
also serves as the package's universally unique identifier and
therefore cannot be changed.
All other properties of the package are stored as attributes and child
elements of the <version>
element, since they can
vary from version to version. The <version>
element
also has two attributes: name
and url
. The
name
attribute is actually a version number that conforms
to the numbering convention defined below. It is called
name
instead of number
, because it can be
alphanumeric, not purely numeric. The name
attribute also
designates the maturity of the package: development, alpha, beta, or
release. As with the <package>
element, the
url
attribute identifies the authoritative distribution
point for the specified version of the package (specifically, the
location of an actual package file that can be downloaded) and serves
as the package version's universally unique identifier.
The version
element contains:
<package-name>
element, which is a pretty
name for the package
<owner>
elements, each of which
identifies a party responsible for maintenance of the package
<summary>
element
<description>
element (optional)
<release-date>
element
<vendor>
element (optional), which
identifies the organization that maintains the package
<provides>
elements, each of which
identifies an interface provided by the package
<requires>
elements, each of which
identifies an interface upon which the package depends
<files>
element, containing one
<file>
element for each
<parameter>
elements that specify
the package's configuration interface
[ACS4]
<provides>
or <requires>
element identifies an interface with the combination of its
url
and version
attributes, where
url
is a universally unique identifier for the interface
(API or UI) and version
is an identifier that conforms to
the same version numbering convention used for packages. The
convention for constructing an interface URL is:
http://vendor-host/packages/logical-name/implementation-type
In the above example, the vendor-host
is
software.arsdigita.com
, the
logical-name
is developer-support
,
and the implementation-type
is
tcl-api
. Other implementation-type
values
include plsql-api
, sql-views
, and
java-api
. (At this time, the result of visiting an
interface URL is undefined; in the future, it will display the
documentation for the identified interface.)
Once an interface is published in an <provides>
element, future versions of the package must maintain that interface,
i.e., no changes can be made to the interface or its implementation
that would cause dependent code to break. The interface can
be augmented, in which case the version number should be incremented,
i.e., a later version of an interface is always the superset of an
earlier version. To communicate the fact that an incompatible change
has been made to an interface, the package owner will remove the
original <provides>
element and add a new,
different <provides>
element, e.g., hypothetically,
we might someday replace developer-support/tcl-api
with
developer-support/tcl-api-2
.
Also, a <provides>
element can include a
deprecated
attribute, meaning that the package owner
expects to remove the corresponding interface in the future.
d
, indicating a development-only version (i.e., definitely broken)
a
, indicating an alpha release (i.e., probably broken)
b
, indicating a beta release (i.e., somewhat broken)
In addition, the letters d
, a
, and
b
may be followed by another integer, indicating a
version within the release.
For those who like regular expressions:
version_number := integer ('.' integer){0,3} (('d'|'a'|'b') integer?)?
So the following is a valid progression for version numbers:
0.9d, 0.9d1, 0.9a1, 0.9b1, 0.9b2, 0.9, 1.0, 1.0.1, 1.1b1, 1.1
.apm
fileNormally, package management systems take all the various files containing programs, data, documentation, and configuration information, and place them in one specially formatted file -- a package file.This description fits APM packages, which are distributed as
gzip
-compressed
tarfiles, with the special extension .apm
. The full
naming convention for APM package files is:
package-key-package-version-name.apm
For instance, the first production release of the ACS Core package
is named acs-core-3.3.0.apm
.
Inside the tarfile, there is one directory at the top level, with the same name as the package key, which, in turn, contains:
www
directory, in which the
implementation of the package's UI (if any) resides
-procs.tcl
define Tcl procedures;
files ending in -init.tcl
contain code to be run at
initialization time (e.g., filter registration).
.sql
extension) that contain the DDL statements to
install the package's database schema and/or the package's
database-resident API (views, stored procedures, stored functions)
upgrade-version-name-next-version-name.sql
(If any of these files are present, they will be located in an
upgrade
subdirectory.)
package-key.html
or package-name.adp
, or a doc
subdirectory containing multiple documentation files
package-key.info
packages
subdirectory of the
server root directory, at the same level as the legacy
www
, tcl
, and parameters
directories (which, by the way, continue to serve the same purposes as
they did in versions of ACS prior to 3.2; we may remove some of this
backward-compatibility in ACS 4).
Thus, the directory structure of the hypothetical ACS 3.3 installation that is illustrated in the diagram above would look something like this:
Another component of the ACS Core package, the Request Processor, is responsible for making the various package user interfaces integrate into one coherent hierarchy of URLs. The basic algorithm used to translate a URL into a filesystem path is simple: "When an HTTP request forserver-root/ | +-- packages/ | +-- acs-core/ | +-- bboard/ | | | +-- doc/ | | | | | +-- index.html | | | | | +-- ... | | | +-- www/ | | | | | +-- admin/ | | | | | | | +-- index.adp | | | | | | | +-- ... | | | | | +-- index.adp | | | | | +-- ... | | | +-- bboard.info | | | +-- bboard.sql | | | +-- bboard-init.tcl | | | +-- bboard-procs.tcl | | | +-- ... | +-- ecommerce/ | +-- ...
/package-key/filename
is received, then
return the file
server-root/packages/package-key/www/filename
."
(In reality, the job of the Request Processor is not so simple.)
server-root/tcl
directory
server-root/www
), which translated directly
into the site's URL hierarchy
server-root/www/doc/sql
directory
key
attribute of the package
element is designed to address.
.info
for package
specifications: perhaps just .xml
?
api
directory
The distribution file containing a package is rooted at the server root, so (for instance) one might find the filepackages/address-book/address-book.html
in the package. If for some reason a package needs to contribute a file to the globalwww
directory rather than its package-private one, the package could just contain the filewww/foo/bar.tcl
; this file would be installed into the site-widewww
directory.Package distribution files can contain files in other packages' directories; this flexibility will be useful in case a package needs to augment another package by providing extra services. For instance, a package providing attachment support for the address book might contain a
packages/address-book/www/view-attachments.tcl
file. However, it could not contain a newpackages/address-book/www/index.tcl
file - we allow a file to belong to only one package. (To provide a "hook" to the attachment package, the address book could use a Package Manager API to determine whether the attachment package is installed, displaying a link toview-attachments.tcl
only in that case.)