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 AptBorrowing 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:
<?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:">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>
The only attributes of the <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.infopackages 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:
server-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/
|
+-- ...
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 for /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 directoryserver-root/www), which translated directly into the site's URL hierarchyserver-root/www/doc/sql directorykey attribute of the package element is designed to address..info for package specifications: perhaps just .xml?api directoryThe distribution file containing a package is rooted at the server root, so (for instance) one might find the filepackages/address-book/address-book.htmlin the package. If for some reason a package needs to contribute a file to the globalwwwdirectory rather than its package-private one, the package could just contain the filewww/foo/bar.tcl; this file would be installed into the site-widewwwdirectory.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.tclfile. However, it could not contain a newpackages/address-book/www/index.tclfile - 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.tclonly in that case.)