Index: openacs-4/packages/acs-core-docs/www/acs-admin.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/acs-admin.html,v diff -u -r1.8.2.7 -r1.8.2.8 --- openacs-4/packages/acs-core-docs/www/acs-admin.html 4 May 2003 06:30:02 -0000 1.8.2.7 +++ openacs-4/packages/acs-core-docs/www/acs-admin.html 7 May 2003 17:40:58 -0000 1.8.2.8 @@ -1,2 +1,2 @@ -
Table of Contents
Table of Contents
+
by Vinod Kurup
OpenACS docs are written by the named authors, and may be edited
by OpenACS documentation staff.
This page assumes you have downloaded aolserver to to -/tmp/aolserver3.3oacs1.tar.gz. If not, +/tmp/aolserver3.3oacs1.tar.gz. If not, get it. It also assumes you are following the 4.6.3-P or 4.6.3-O Reference Platform installation, using Red Hat 8.0. Places where other systems are different are noted.
- As root, untar - aolserver3.3oacs1.tar.gz - into /usr/local/src. + As root, untar + aolserver3.3oacs1.tar.gz + into /usr/local/src. -
[root@yourserver root]# cd /usr/local/src -[root@yourserver src]# tar xzf /tmp/aolserver3.3oacs1.tar.gz +[root@yourserver root]# cd /usr/local/src +[root@yourserver src]# tar xzf /tmp/aolserver3.3oacs1.tar.gz [root@yourserver src]# -cd /usr/local/src -tar xzf /tmp/aolserver3.3oacs1.tar.gz
Compile and install AOLserver. First, prepare the installation directory and the source code. The message about BUILD-MODULES can be ignored.
root@yourserver root]# mkdir -p /usr/local/aolserver
-[root@yourserver root]# cd /usr/local/src/aolserver
-[root@yourserver aolserver]# ./conf-clean
+cd /usr/local/src
+tar xzf /tmp/aolserver3.3oacs1.tar.gz
Compile and install AOLserver. First, prepare the installation directory and the source code. The message about BUILD-MODULES can be ignored.
root@yourserver root]# mkdir -p /usr/local/aolserver +[root@yourserver root]# cd /usr/local/src/aolserver +[root@yourserver aolserver]# ./conf-clean cat: BUILD-MODULES: No such file or directory Done. -[root@yourserver aolserver]#mkdir -p /usr/local/aolserver +[root@yourserver aolserver]#mkdir -p /usr/local/aolserver cd /usr/local/src/aolserver -./conf-clean
+./conf-clean
If you are using Oracle, edit - conf-db and change - postgresql to - oracle, or to the word - both if you want both drivers + conf-db and change + postgresql to + oracle, or to the word + both if you want both drivers installed. In order to get nsoracle to compile, you may need to su - oracle, and then su (without the -) root to set the environment variables properly. -
conf-inst should contain the +
conf-inst should contain the location where AOLserver is to be installed. Overwrite the - tarball's default value with our default value, /usr/local/aolserver:
[root@yourserver aolserver]# echo "/usr/local/aolserver" > conf-inst -[root@yourserver aolserver]#
conf-make should contain the + tarball's default value with our default value, /usr/local/aolserver:
[root@yourserver aolserver]# echo "/usr/local/aolserver" > conf-inst +[root@yourserver aolserver]#
conf-make should contain the name of the GNU Make command on your system. It defaults to - gmake.
Set an environment variable that the nspostgres driver + gmake.
Set an environment variable that the nspostgres driver Makefile needs to compile correctly and run - conf, which compiles - AOLserver, the default modules, and the database driver, and installs them.
[root@yourserver aolserver]# export POSTGRES=/usr/local/pgsql; ./conf + conf, which compiles + AOLserver, the default modules, and the database driver, and installs them.[root@yourserver aolserver]# export POSTGRES=/usr/local/pgsql; ./conf Building in /usr/local/aolserver with the following modules: aolserver @@ -60,55 +60,55 @@ ================================================================== Done Building Sat Mar 8 10:31:35 PST 2003 [root@yourserver aolserver]#- This takes about 5 minutes. It builds aolserver, several modules, and the database driver. (Upgraders, note that the postgres database driver has changed from postgres.so to nspostgres.so). All of the results are logged to files in /usr/local/src/aolserver/log. If you run into problems running AOLserver, check these files for build errors.
Add a database-specific wrapper script. This script + This takes about 5 minutes. It builds aolserver, several modules, and the database driver. (Upgraders, note that the postgres database driver has changed from postgres.so to nspostgres.so). All of the results are logged to files in /usr/local/src/aolserver/log. If you run into problems running AOLserver, check these files for build errors.
Add a database-specific wrapper script. This script sets database environment variables before starting AOLserver; this allows the AOLserver instance can communicate with the database. There is one script each for Oracle and PostGreSQL. They don't conflict, so if you plan - to use both databases, install both.
Oracle
[root@yourserver aolserver]# cd /usr/local/aolserver/bin -[root@yourserver bin]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/nsd-oracle.txt ./nsd-oracle -[root@yourserver bin]# chmod 750 nsd-oracle + to use both databases, install both.
Oracle
[root@yourserver aolserver]# cd /usr/local/aolserver/bin +[root@yourserver bin]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/nsd-oracle.txt ./nsd-oracle +[root@yourserver bin]# chmod 750 nsd-oracle [root@yourserver bin]# -cd /usr/local/aolserver/bin +cd /usr/local/aolserver/bin cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/nsd-oracle.txt ./nsd-oracle -chmod 750 nsd-oracle
PostGreSQL
[root@yourserver aolserver]# cd /usr/local/aolserver/bin -[root@yourserver bin]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/nsd-postgres.txt ./nsd-postgres -[root@yourserver bin]# chmod 755 nsd-postgres +chmod 750 nsd-oraclePostGreSQL
[root@yourserver aolserver]# cd /usr/local/aolserver/bin +[root@yourserver bin]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/nsd-postgres.txt ./nsd-postgres +[root@yourserver bin]# chmod 755 nsd-postgres [root@yourserver bin]# -cd /usr/local/aolserver/bin +cd /usr/local/aolserver/bin cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/nsd-postgres.txt ./nsd-postgres -chmod 755 nsd-postgres
OPTIONAL - install nsopenssl. This AOLserver module +chmod 755 nsd-postgres
OPTIONAL - install nsopenssl. This AOLserver module is required if you want people to connect to your site via https. These commands compile nsopenssl and install it, along with a tcl helper script to handle https connections. You will also need ssl certificates. Because those should be different for each server service, you won't need those instructions until later. You will need the nsopenssl tarball in - /tmp.
(Red Hat 9 note: see this - thread for details on compiling nsopenssl.)
[root@yourserver bin]# cd /usr/local/src/aolserver -[root@yourserver aolserver]# tar xzf /tmp/nsopenssl-2.1.tar.gz -[root@yourserver aolserver]# cd nsopenssl-2.1 -[root@yourserver nsopenssl-2.1]# make OPENSSL=/usr/local/ssl + /tmp.(Red Hat 9 note: see this + thread for details on compiling nsopenssl.)
[root@yourserver bin]# cd /usr/local/src/aolserver +[root@yourserver aolserver]# tar xzf /tmp/nsopenssl-2.1.tar.gz +[root@yourserver aolserver]# cd nsopenssl-2.1 +[root@yourserver nsopenssl-2.1]# make OPENSSL=/usr/local/ssl gcc -I/usr/local/ssl/include -I../aolserver/include -D_REENTRANT=1 -DNDEBUG=1 -g -fPIC -Wall -Wno-unused -mcpu=i686 -DHAVE_CMMSG=1 -DUSE_FIONREAD=1 -DHAVE_COND_EINTR=1 -c -o nsopenssl.o nsopenssl.c (many lines omitted) gcc -shared -nostartfiles -o nsopenssl.so nsopenssl.o config.o init.o ssl.o thread.o tclcmds.o -L/usr/local/ssl/lib -lssl -lcrypto -[root@yourserver nsopenssl-2.1]# cp nsopenssl.so /usr/local/aolserver/bin -[root@yourserver nsopenssl-2.1]# cp https.tcl /usr/local/aolserver/modules/tcl/ +[root@yourserver nsopenssl-2.1]# cp nsopenssl.so /usr/local/aolserver/bin +[root@yourserver nsopenssl-2.1]# cp https.tcl /usr/local/aolserver/modules/tcl/ [root@yourserver nsopenssl-2.1]# -cd /usr/local/src/aolserver +cd /usr/local/src/aolserver tar xzf /tmp/nsopenssl-2.1.tar.gz cd nsopenssl-2.1 make OPENSSL=/usr/local/ssl cp nsopenssl.so /usr/local/aolserver/bin -cp https.tcl /usr/local/aolserver/modules/tcl/
For Debian (more - information):
apt-get install libssl-dev -make OPENSSL=/usr/lib/ssl
OPTIONAL - install OpenFTS. If you want full text search, +cp https.tcl /usr/local/aolserver/modules/tcl/
For Debian (more + information):
apt-get install libssl-dev
+make OPENSSL=/usr/lib/ssl
OPTIONAL - install OpenFTS. If you want full text search, and you are running PostGreSQL, install this module to support FTS. You will need the openfts - tarball in /tmp.
Install Tsearch. This is a PostGreSQL module that - OpenFTS requires.
[root@yourserver root]# su - postgres -[postgres@yourserver pgsql]$ cd /usr/local/src/postgresql-7.2.4/contrib/tsearch/ -[postgres@yourserver tsearch]$ make + tarball in /tmp.
Install Tsearch. This is a PostGreSQL module that + OpenFTS requires.
[root@yourserver root]# su - postgres +[postgres@yourserver pgsql]$ cd /usr/local/src/postgresql-7.2.4/contrib/tsearch/ +[postgres@yourserver tsearch]$ make sed 's,MODULE_PATHNAME,$libdir/tsearch,g' tsearch.sql.in >tsearch.sql /usr/bin/flex -8 -Ptsearch_yy -o'parser.c' parser.l (many lines omitted) @@ -123,74 +123,74 @@ logout [root@yourserver root]# -su - postgres +su - postgres cd /usr/local/src/postgresql-7.2.4/contrib/tsearch make make install -exit
Unpack the OpenFTS tarball and compile and install - the driver.
[root@yourserver root]# cd /usr/local/src -[root@yourserver src]# tar xzf /tmp/Search-OpenFTS-tcl-0.3.2.tar.gz -[root@yourserver src]# cd /usr/local/src/Search-OpenFTS-tcl-0.3.2/ -[root@yourserver Search-OpenFTS-tcl-0.3.2]# ./configure --with-aolserver-src=/usr/local/src/aolserver/aolserver --with-tcl=/usr/lib/ +exitUnpack the OpenFTS tarball and compile and install + the driver.
[root@yourserver root]# cd /usr/local/src +[root@yourserver src]# tar xzf /tmp/Search-OpenFTS-tcl-0.3.2.tar.gz +[root@yourserver src]# cd /usr/local/src/Search-OpenFTS-tcl-0.3.2/ +[root@yourserver Search-OpenFTS-tcl-0.3.2]# ./configure --with-aolserver-src=/usr/local/src/aolserver/aolserver --with-tcl=/usr/lib/ checking prefix... /usr/local checking for gcc... gcc (many lines omitted) configure: creating ./config.status config.status: creating Makefile.global -[root@yourserver Search-OpenFTS-tcl-0.3.2]# make +[root@yourserver Search-OpenFTS-tcl-0.3.2]# make (cd parser; make all) make[1]: Entering directory `/usr/local/src/Search-OpenFTS-tcl-0.3.2/parser' (many lines omitted) packages provided were {Lingua::Stem::Snowball 0.3.2} processed fts_base_snowball.tcl -[root@yourserver Search-OpenFTS-tcl-0.3.2]# cd aolserver -[root@yourserver aolserver]# make +[root@yourserver Search-OpenFTS-tcl-0.3.2]# cd aolserver +[root@yourserver aolserver]# make gcc -c -fPIC -DPACKAGE=\"OPENFTS\" -DVERSION=\"0.3.2\" -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STR (many lines omitted) n_stem.o italian_stem.o norwegian_stem.o portuguese_stem.o russian_stem.o nsfts.o -o nsfts.so -[root@yourserver aolserver]# cp nsfts.so /usr/local/aolserver/bin/ +[root@yourserver aolserver]# cp nsfts.so /usr/local/aolserver/bin/ [root@yourserver aolserver]# -cd /usr/local/src +cd /usr/local/src tar xzf /tmp/Search-OpenFTS-tcl-0.3.2.tar.gz cd /usr/local/src/Search-OpenFTS-tcl-0.3.2/ ./configure --with-aolserver-src=/usr/local/src/aolserver/aolserver --with-tcl=/usr/lib/ make cd aolserver make cp nsfts.so /usr/local/aolserver/bin -
Build some supplemental modules.
[root@yourserver aolserver]# cd .. -[root@yourserver Search-OpenFTS-tcl-0.3.2]# cp -r pgsql_contrib_openfts /usr/local/src/postgresql-7.2.4/contrib -[root@yourserver Search-OpenFTS-tcl-0.3.2]# cd /usr/local/src/postgresql-7.2.4/contrib/pgsql_contrib_openfts -[root@yourserver pgsql_contrib_openfts]# make +Build some supplemental modules.
[root@yourserver aolserver]# cd .. +[root@yourserver Search-OpenFTS-tcl-0.3.2]# cp -r pgsql_contrib_openfts /usr/local/src/postgresql-7.2.4/contrib +[root@yourserver Search-OpenFTS-tcl-0.3.2]# cd /usr/local/src/postgresql-7.2.4/contrib/pgsql_contrib_openfts +[root@yourserver pgsql_contrib_openfts]# make sed 's,MODULE_PATHNAME,$libdir/openfts,g' openfts.sql.in >openfts.sql gcc -O2 -Wall -Wmissing-prototypes -Wmissing-declarations -fpic -I. -I../../src/include -c -o openfts.o openfts.c gcc -shared -o openfts.so openfts.o rm openfts.o -[root@yourserver pgsql_contrib_openfts]# su postgres -[postgres@yourserver pgsql_contrib_openfts]$ make install +[root@yourserver pgsql_contrib_openfts]# su postgres +[postgres@yourserver pgsql_contrib_openfts]$ make install /bin/sh ../../config/install-sh -c -m 644 openfts.sql /usr/local/pgsql/share/contrib /bin/sh ../../config/install-sh -c -m 755 openfts.so /usr/local/pgsql/lib /bin/sh ../../config/install-sh -c -m 644 ./README.openfts /usr/local/pgsql/doc/contrib -[postgres@yourserver pgsql_contrib_openfts]$ exit +[postgres@yourserver pgsql_contrib_openfts]$ exit [root@yourserver pgsql_contrib_openfts]# -cd .. +cd .. cp -r pgsql_contrib_openfts /usr/local/src/postgresql-7.2.4/contrib cd /usr/local/src/postgresql-7.2.4/contrib/pgsql_contrib_openfts make su postgres make install -exit
In order to test AOLserver, we'll run it using the sample-config.tcl file provided in the AOLserver distribution, - under the nobody user and web + under the nobody user and web group. The sample-config.tcl configuration writes to the default log locations, so we need to give it permission to do so - or it will fail. Grant the web + or it will fail. Grant the web group permission to write to - /usr/local/aolserver/log and - /usr/local/aolserver/servers.
[root@yourserver root]# cd /usr/local/aolserver -[root@yourserver aolserver]# chown -R root.web log servers -[root@yourserver aolserver]# chmod -R g+w log servers -[root@yourserver aolserver]# ls -l + /usr/local/aolserver/log and + /usr/local/aolserver/servers.[root@yourserver root]# cd /usr/local/aolserver +[root@yourserver aolserver]# chown -R root.web log servers +[root@yourserver aolserver]# chmod -R g+w log servers +[root@yourserver aolserver]# ls -l total 32 drwxr-sr-x 2 root root 4096 Mar 8 12:57 bin drwxr-xr-x 3 root root 4096 Mar 8 10:34 include @@ -200,15 +200,15 @@ -rw-r--r-- 1 root root 7320 Mar 31 2001 sample-config.tcl drwxrwsr-x 3 root web 4096 Mar 8 10:31 servers [root@yourserver aolserver]# -+cd /usr/local/aolserver chown -R root.web log servers chmod -R g+w log servers -ls -l
Now, we'll run a quick test to ensure AOLserver is running +ls -l
Now, we'll run a quick test to ensure AOLserver is running correctly. We'll use the sample config file provided with AOLserver. This file will attempt to guess your IP address and hostname. It will then start up the server at port 8000 of that - IP address.
[root@yourserver aolserver]# ./bin/nsd -t sample-config.tcl -u nobody -g web + IP address.[root@yourserver aolserver]# ./bin/nsd -t sample-config.tcl -u nobody -g web [root@yourserver aolserver]# [08/Mar/2003:15:07:18][31175.8192][-main-] Notice: config.tcl: starting to read config file... [08/Mar/2003:15:07:18][31175.8192][-main-] Warning: config.tcl: nsssl not loaded -- key/cert files do not exist. [08/Mar/2003:15:07:18][31175.8192][-main-] Warning: config.tcl: nscp not loaded @@ -217,32 +217,32 @@ config file.The first warning, about nsssl, can be ignored. We won't be using nsssl; we'll be using nsopenssl instead, and we haven't fully configured it yet. The nscp warning refers to the fact that, without a user and password in the config file, the administrative panel of AOLserver won't load. We don't plan to use it and can ignore that error as well. Any other warning or error is unexpected and probably a problem.
Test to see if AOLserver is working by starting - Mozilla or - Lynx on the same + Mozilla or + Lynx on the same computer and surfing over to your web page. If you browse from another computer and the sample config file didn't guess your hostname or ip correctly, you'll get a false negative test. -
[root@yourserver aolserver]# lynx localhost:8000+
[root@yourserver aolserver]# lynx localhost:8000You should see a "Welcome to AOLserver" page. If this doesn't work, try going to - http://127.0.0.1:8000/. If this + http://127.0.0.1:8000/. If this still doesn't work, check out the Troubleshooting AOLserver section below. Note that you will not be able to browse to the web page from another machine, because AOLserver is only listening to the local address. -
Shutdown the test server:
[root@yourserver aolserver]# killall nsd +Shutdown the test server:
[root@yourserver aolserver]# killall nsd [root@yourserver aolserver]#- The killall command will kill - all processes with the name nsd, + The killall command will kill + all processes with the name nsd, but clearly this is not a good tool to use for managing your services in general. We cover this topic in the Keep AOLServer alive section.
If you can't view the welcome page, it's likely there's a problem with your server configuration. Start by viewing your AOLserver log, which is in - /usr/local/aolserver/log/server.log. + /usr/local/aolserver/log/server.log. You should also try to find lines of the form:
@@ -252,12 +252,12 @@ If you can find these lines, try entering the URL the server is listening on. If you cannot find these lines, there must be an error somewhere in the file. Search for lines beginning with the word - Error instead of - Notice. + Error instead of + Notice.- The sample-config.tcl file grabs + The sample-config.tcl file grabs your address and hostname from your OS settings.
@@ -267,30 +267,30 @@ If you get an error that nssock can't get the requested address, you can set these manually. If you type 0.0.0.0, AOLserver will try to listen on all available addresses. Note: - ns_info address doesn't appear + ns_info address doesn't appear to be supported in current versions of AOLserver.set hostname [ns_info hostname] #set address [ns_info address] set address 0.0.0.0
OPTIONAL - install Analog web file analyser. You should have the source tarball in -/tmp. Unpack, compile, and install analog.
[root@yourserver aolserver]# cd /usr/local/src -[root@yourserver src]# tar xzf /tmp/analog-5.31.tar.gz -[root@yourserver src]# cd analog-5.31 -[root@yourserver analog-5.31]# make +/tmp. Unpack, compile, and install analog.[root@yourserver aolserver]# cd /usr/local/src +[root@yourserver src]# tar xzf /tmp/analog-5.31.tar.gz +[root@yourserver src]# cd analog-5.31 +[root@yourserver analog-5.31]# make cd src && make make[1]: Entering directory `/usr/local/src/analog-5.31/src' (many lines omitted) ***IMPORTANT: You must read the licence before using analog *** make[1]: Leaving directory `/usr/local/src/analog-5.31/src' -[root@yourserver analog-5.31]# cd .. -[root@yourserver src]# mv analog-5.31 /usr/share/ +[root@yourserver analog-5.31]# cd .. +[root@yourserver src]# mv analog-5.31 /usr/share/ [root@yourserver src]# -cd /usr/local/src +cd /usr/local/src tar xzf /tmp/analog-5.31.tar.gz cd analog-5.31 make cd .. -mv analog-5.31 /usr/share/
+
by Bryan Quinn
OpenACS docs are written by the named authors, and may be edited
by OpenACS documentation staff.
-
Tcl API
Tcl API
apm-install-procs.tcl (Supports installation of packages)
20-apm-load-procs.tcl (Bootstraps APM for server startup)
-apm-admin-procs.tcl (Supports APM UI)
PL/SQL file
PL/SQL file
In general terms, a package is a unit of software that serves a single well-defined purpose. That purpose may be to provide a service directly to one or more classes of end-user, (e.g., discussion forums @@ -44,7 +44,7 @@ installation through APM is another potential package instance that can become part of Jane's View Camera subsite.
The APM provides an architecture for packaging software, making instances of that software available to subsites, specifying configuration parameters -for each instance, and managing the creation and release of new packages.
+for each instance, and managing the creation and release of new 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 @@ -89,8 +89,8 @@ packages for other ACS users to download and install.
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 e-commerce):
APM itself is part of a package, the OpenACS Kernel, an OpenACS -service that is the only mandatory component of an OpenACS installation.
The OpenACS is a platform for web-based application software, and any software +3.2 (say, bboard and e-commerce):
APM itself is part of a package, the OpenACS Kernel, an OpenACS +service that is the only mandatory component of an OpenACS installation.
The OpenACS is a platform for web-based application software, and any software platform has the potential to develop problems like those described above. Fortunately, there are many precedents for systematic solutions, including:
Debian GNU/Linux and the Debian @@ -103,7 +103,7 @@ integrated with filesystem-based version control -
web-based tools for package development:
creating new packages locally
releasing new versions of locally-created packages
The design chosen for APM was meant to satisfy the following constraints:
The process of authoring a package must be as simple as possible.
Strict conventions must be established that provide a set of canonical locations and names for files and patterns, for OpenACS application @@ -122,7 +122,7 @@ documentation walks the developer through each of these steps. Moreover, from following these steps, the package can be subsite specific, available to subsites across the system, and be available for distribution to other OpenACS -installations without doing a monolithic upgrade or reinstall.
The APM is composed of systems for accomplishing a set of package-related +installations without doing a monolithic upgrade or reinstall.
The APM is composed of systems for accomplishing a set of package-related tasks. Each of these tasks comprise a feature area that has an API, data model, and a UI:
Authoring a Package
Maintaining Multiple Versions of a Package
Creating Instances of the Package
Specifying Configuration Parameters for each Instance
Authoring a Package
Full instructions on how to prepare an OpenACS package are available in Packages. The API here can be invoked manually by a package's data model
creation script, but need not to be used. This API is part of the APM PL/SQL
@@ -145,9 +145,9 @@
The procedure above registers an OpenACS application in the APM. It creates a
new OpenACS object and stores information about the package, such as its name, in
the APM data model. There is an analogous procedure for OpenACS services, called
-apm.register_service. To remove an application from the system, there are the calls
-apm.unregister_application and
-apm.unregister_service.
+apm.register_service.
To remove an application from the system, there are the calls +apm.unregister_application and +apm.unregister_service.
-- Remove the application from the system. procedure unregister_application ( @@ -156,10 +156,10 @@ cascade_p in char default 'f' ); -
Use the cascade_p only if you want to completely remove the +
Use the cascade_p only if you want to completely remove the package from the OpenACS.
In order to determine if a particular package exists in the system, use -the register_p predicate. It returns 1 if the specified -package_key exists in the system, 0 otherwise.
+the register_p predicate. It returns 1 if the specified +package_key exists in the system, 0 otherwise.function register_p ( package_key in apm_package_types.package_key%TYPE @@ -170,8 +170,8 @@ between versions, the owner of a package, its vendor, its URI, and its dependency information may change. The API for package versions allows this information to be specified. All of these APIs are part of the -apm_package_version PL/SQL package.To create a new package version, use the -apm_package_version.new constructor function.
+apm_package_version PL/SQL package.To create a new package version, use the +apm_package_version.new constructor function.
function new ( version_id in apm_package_versions.version_id%TYPE @@ -192,26 +192,26 @@ default 'f' ) return apm_package_versions.version_id%TYPE; -In order to use this function, an existing package_key must -be specified. The version_name parameter must follow a strict +
In order to use this function, an existing package_key must +be specified. The version_name parameter must follow a strict convention:
A major version number
at least one minor version number. Although any number of minor version numbers may be included, three minor version numbers is sufficient and is the -convention of software developers.
One of the following:
The letter d, indicating a development-only version
The letter a, indicating an alpha release
The letter b, indicating a beta release
No letter at all, indicating a final production release
In addition, the letters d, a, and -b may be followed by another integer, indicating a version +convention of software developers.
One of the following:
The letter d, indicating a development-only version
The letter a, indicating an alpha release
The letter b, indicating a beta release
No letter at all, indicating a final production release
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 := ^[0-9]+((\.[0-9]+)+((d|a|b|)[0-9]?)?)$ -
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, +
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
To delete a given version of a package, use the -apm_package_version.delete procedure:
+apm_package_version.delete procedure:procedure delete ( package_id in apm_packages.package_id%TYPE );After creating a version, it is possible to edit the information -associated with it using apm_package_version.edit.
+associated with it using apm_package_version.edit.function edit ( new_version_id in apm_package_versions.version_id%TYPE @@ -246,7 +246,7 @@Files associated with a version can be added and removed. The path is relative to the package-root which is -acs-server-root/packages/package-key.
+acs-server-root/packages/package-key.-- Add a file to the indicated version. function add_file( file_id in apm_package_files.file_id%TYPE @@ -383,7 +383,7 @@Specifying Configuration Parameters for each Instance
A parameter is a setting that can be changed on a package instance basis. -Parameters are registered on each package_key, and the values +Parameters are registered on each package_key, and the values are associated with each instance. Parameters can have default values and can be of type 'string' or 'number.' There is support with this API for setting a number of minimum and maximum values for each parameter, @@ -464,65 +464,65 @@ attr_value in apm_parameter_values.attr_value%TYPE ); -
The central piece of the data model is the apm_package_types table where each package is registered. When a new application or service is installed on an OpenACS instance, a corresponding row in this table is inserted with information about the type of package, e.g. if the bboard package is installed on your OpenACS server, a row -in apm_package_types will be created, noting that it's an -application package type.
The apm_packages table is used to contain information about +in apm_package_types will be created, noting that it's an +application package type.
The apm_packages table is used to contain information about the instances of packages currently created in the system. The -package_key column references the apm_package_types +package_key column references the apm_package_types table to ensure that no package instance can be created for a type that does -not exist.
The apm_package_versions table contains information specific +not exist.
The apm_package_versions table contains information specific to a particular version of a package. Several tables reference this one to -provide further information about the particular version:
apm_package_owners +provide further information about the particular version:
apm_package_owners Stores information about the owners of a particular version of a package. -
apm_package_files +
apm_package_files Stores information about the files that are part of a version. -
apm_package_dependencies +
apm_package_dependencies Stores information about what interfaces the package provides and -requires.
Parameter information is maintained through two tables:
apm_parameters +requires.
Parameter information is maintained through two tables:
apm_parameters This table contains the definition of each of the parameters for a package. -
apm_parameter_values +
apm_parameter_values This table holds all of the values of parameters for specific package instances.
A number of views are available for obtaining information about packages -registered in the APM.
apm_package_version_info +registered in the APM.
apm_package_version_info Provides information about all of the versions in the system with -information available from the apm_package_types table. +information available from the apm_package_types table. -
apm_enabled_package_versions +
apm_enabled_package_versions A view (subset) of the above table with only enabled versions. -
apm_file_info - Provides a public interface for querying file information.
The APM's user interface is part of the +
apm_file_info + Provides a public interface for querying file information.
The APM's user interface is part of the OpenACS Administration Service. The UI is the primary point of contact with APM by developers and administrators. It is part of OpenACS Administration, because only the site-wide administrator should be able to access it. Thus in order to develop a package, the developer must be granted -site-wide administration.
APM has two parameters for configuring how it interacts with the UNIX +site-wide administration.
APM has two parameters for configuring how it interacts with the UNIX filesystem, accessible via the Site Map admin page. These parameters need not be changed under most circumstances, but may need to be tweaked for Windows compatibility.
GzipExecutableDirectory - This directory points to where the gunzip program can be found -for uncompressing gzip archives. This is needed for the -installation of .apm files which are simply gziped -tarballs. Default is /usr/local/bin + This directory points to where the gunzip program can be found +for uncompressing gzip archives. This is needed for the +installation of .apm files which are simply gziped +tarballs. Default is /usr/local/bin
InfoFilePermissionsMode This sets the default UNIX permissions used when creating files using the -APM. Default is 775.
APM has been in production since OpenACS 3.3, and as of version 4.0 offers a stable set of features. One major feature planned is integration with the OpenACS Package Repository for automatic dependency satisfaction. When a user tries to install a package that depends on other packages, the APM will contact the @@ -540,6 +540,6 @@ repositories worldwide.
Another anticipated change is to split the APM UI into separate systems for authoring, maintaining, and installing packages. The current UI presents all of this functionality in one interface and it can be confusing from a -usability perspective.
System creator: Bryan Quinn, Jon Salz, Michael Yoon, Lars Pind, Todd +usability perspective.
System creator: Bryan Quinn, Jon Salz, Michael Yoon, Lars Pind, Todd Nightingale.
System owner: Bryan Quinn
Documentation author: Bryan Quinn, building from earlier versions by Jon -Salz, Michael Yoon, and Lars Pind.
+
by Bryan Quinn and Todd Nightingale
OpenACS docs are written by the named authors, and may be edited
by OpenACS documentation staff.
-
The following is a requirements document for the OpenACS Package Manager (APM), version 4.0 (APM4). APM4 offers a superset of APM v3.3 functionality with the following specific enhancements:
A public procedural API. (v 3.3 only has web-based UI)
Support for dependency checking.
Support for compound packages (to support installation chaining).
Support for on-line parameter setting.
Support for sub-site level configuration (requires revised ad_parameter and /admin pages at sub-site level; deprecation of site-wide parameter @@ -13,7 +13,7 @@ documentation which suggested these features, as well as the influence of the design and open-source implementation of the Red Hat Package manager, the Debian packaging system, and PERL's CPAN in the development of the ideas -behind this document.
A typical website will tend to offer its users a number of web-based +behind this document.
A typical website will tend to offer its users a number of web-based services or applications, e.g. a bulletin board, calendaring, classified ads, etc. A website may also have underlying subsystems, such as a permissions system, content management system, etc. For such applications and subsystem @@ -27,7 +27,7 @@ OpenACS sites.
In general terms, a package is a unit of software that serves a single well-defined purpose. The OpenACS Package Manager (APM) provides a mechanism for packaging, installing, and configuring OpenACS software in a consistent, -user-friendly, and subsite-aware manner.
The OpenACS Package Manager (APM) consists of:
A standard format for APM packages including:
Version numbering, independent of any other package and the OpenACS as a whole
Specification of the package interface
Specification of dependencies on other packages (if any)
Attribution (who wrote it) and ownership (who maintains it)
Web-based tools for package management:
Obtaining packages from a remote distribution point
Installing packages, if and only if:
All prerequisite packages are installed
No conflicts will be created by the installation
Configuring packages (obsoleting the monolithic OpenACS configuration @@ -39,7 +39,7 @@ should never break an OpenACS installation
Web-based tools for package configuration:
The ability to change package parameter values on-line through a simple web interface.
A new ad_parameter which does not require a monolithic site-wide parameter's file or server restarts for changes to take effect.
The ability to manage multiple package instances at the sub-site -level.
The APM is intended for the following classes of users, which may or may not overlap:
Developers (referred to as 'the developer') use the APM to create a software package for distribution and use the procedural @@ -96,7 +96,7 @@ different actions depending on what version of another package is installed. She uses the APM procedural API to check if KM version 1.0 is installed or version 1.1. Based on the results of this procedural call, the software -exhibits different behavior.
4.500.0 Package Identification +exhibits different behavior.
4.500.0 Package Identification (All of these items are entered by the developer using the developer UI.)
4.500.1 A human readable package key that is guaranteed to be unique to the local OpenACS site must be maintained by the APM. For example, "apm."
4.500.5 A package id (primary key) that is guaranteed to @@ -110,7 +110,7 @@ be unique to the local site must be maintained by the APM.
4.505.5 A version URL that is guaranteed to be unique across all sites must be maintained by the APM. The version URL should point to a server that allows download of a specific version of the package. -
The API for APM v3 is explicitly a private API. However, it would be useful to obtain information from the APM through a procedural API. Implementing the API specified below is quite easy given that there are pages that already do all of the below in raw SQL.
4.400.0 Packages Status Predicates
4.400.1 Given defining information such as a package URL, @@ -124,16 +124,16 @@ admins. The subsite parameter can be set to be non-persistent (but default is to survive server restarts). The subsite parameter can also be set to only take effect after a server restart (default is immediate).
4.415.5 Parameters for a given subsite and package can be -returned by the system API.
Provisions will be made to assure that packages are securely identified.
4.600.1 Each package will have a PGP signature and there will be MD5 time stamps for each file within the package.
4.600.5 The APM will provide a facility to validate both -the PGP signature and MD5 stamps information before a package install.
The user interface is a set of HTML pages that are used to drive the underlying API. It is restricted to site-wide administrators because the -actions taken here can dramatically affect the state of the running OpenACS.
The intent of the developer's interface is to enable the developer to +actions taken here can dramatically affect the state of the running OpenACS.
The intent of the developer's interface is to enable the developer to construct and maintain APM packages. It will be possible to disable the developer's interface for production sites to help reduce the chance of site failure; much of the functionality here can have cascading effects @@ -197,12 +197,12 @@ allow for separation of optional and required components from the installation as well as better organization of files once installed. For example, all documentation for the community-core can be packages as -community-core-doc.apm. It is legal to include sub-packages with +community-core-doc.apm. It is legal to include sub-packages with dependencies that are not satisfied by the packages in the compound package, but this is discouraged. In such a case, the sub-package should really be a separate package that is required by the compound package.
4.200.10 If a sub-package is required for the installation of the compound package, the compound package should have a -registered dependency on the sub-package.
The requirement of the administrator's interface is to enable the +registered dependency on the sub-package.
The requirement of the administrator's interface is to enable the administrator to install, enable, upgrade, disable, deinstall, and delete packages.
80.0 Package Enable/Disable
4.80.1 The administrator should be able mark an installed package as enabled. This means that the package is activated and its @@ -260,7 +260,7 @@ consequences throughout a site and should almost never be done.
150.0 Scan for new or modified packages
150.1 The administrator should be able to scan the file system for any changes made in any of the installed package files.
150.5 The administrator should be able to scan the file system for any newly installed packages. -
If the developer is in charge of creating packages and the administrator for installing them, then the sub-site administrator is responsible for configuring and enabling packages. In order for a package to be available for @@ -284,7 +284,7 @@ only the package instance, but any and all content associated with it. It is questionable whether this option should even be available due to its drastic consequences. Reviewer comments appreciated. -
Despite the fact that requirements are meant to be design/implementation neutral, the following thoughts were in our head when specifying these requirements. You must be familiar with the new object design for this to be comprehensible.
When a package is installed system-wide, a corresponding acs_object_type @@ -293,4 +293,4 @@ are set using the acs_attribute_values table. The automatic web interface for setting package parameters should be one and the same with the interface for setting acs object attribute values. Consequently, the implementation of -these features should be quite straightforward.
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 8/10/2000 | Bryan Quinn, Todd Nightingale |
� | Reviewed | 8/11/2000 | John Prevost, Mark Thomas, and Pete Su |
0.2 | Revised and updated | 8/12/2000 | Bryan Quinn |
0.3 | Reviewed, revised, and updated - conforms to requirements template. | 8/18/2000 | Kai Wu |
0.4 | Minor edits before ACS 4 Beta. | 9/30/2000 | Kai Wu |
Prev | Home | Next |
OpenACS 4 Subsites Design Document | Up | OpenACS 4.6.3 Package Manager Design |
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 8/10/2000 | Bryan Quinn, Todd Nightingale |
� | Reviewed | 8/11/2000 | John Prevost, Mark Thomas, and Pete Su |
0.2 | Revised and updated | 8/12/2000 | Bryan Quinn |
0.3 | Reviewed, revised, and updated - conforms to requirements template. | 8/18/2000 | Kai Wu |
0.4 | Minor edits before ACS 4 Beta. | 9/30/2000 | Kai Wu |
Prev | Home | Next |
OpenACS 4 Subsites Design Document | Up | OpenACS 4.6.3 Package Manager Design |
+
by Don Baccus
with additions by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited
by OpenACS documentation staff.
-
The purpose of backup is to enable recovery. Backup and recovery are always risky; here are some steps that minimize the chance recovery is necessary: @@ -33,74 +33,74 @@ OpenACS installations comprise files and database contents. If you follow the reference install and put all files, including configuration files, in - /web/servicename/, + /web/servicename/, and back up the database nightly to a file in - /web/servicename/database-backup, + /web/servicename/database-backup, then you can apply standard file-based backup strategies to the root directory. -
A quick way to automate database backup is a cron job. (This should moved into OpenACS's scheduled task project so that - it's integrated with OpenACS's alerts and such.)
[service0@yourserver service0]$ export EDITOR=emacs;crontab -e
Add this line to the file. The numbers and stars at the beginning are cron columns that specify when the program should be run - in this case, whenever the minute is 0 and the hour is 1, i.e., 1:00 am every day.
0 1 * * * /usr/local/pgsql/bin/pg_dump -f /web/service0/database-backup/service0_$(date +%Y-%m-%d).dmp service0
Here's a quick manual way to back up a reference install - + it's integrated with OpenACS's alerts and such.)
[service0@yourserver service0]$ export EDITOR=emacs;crontab -e
Add this line to the file. The numbers and stars at the beginning are cron columns that specify when the program should be run - in this case, whenever the minute is 0 and the hour is 1, i.e., 1:00 am every day.
0 1 * * * /usr/local/pgsql/bin/pg_dump -f /web/service0/database-backup/service0_$(date +%Y-%m-%d).dmp service0
Here's a quick manual way to back up a reference install - it should be replaced by an automated script within OpenACS. The command excludes the auto-generated - supervise directory, which is - unneccesary and has complicated permissions. Make sure that you are using the cron job to back up the database to a file in /web/service0/database-backup so that the tar command will include the database.
[root@yourserver root]# su - service0 -[service0@yourserver service0]$ tar -cpsj --exclude /web/service0/etc/daemontools/supervise --file /tmp/service0-backup.tar.bz2 /web/service0/ + supervise directory, which is + unneccesary and has complicated permissions. Make sure that you are using the cron job to back up the database to a file in /web/service0/database-backup so that the tar command will include the database.[root@yourserver root]# su - service0 +[service0@yourserver service0]$ tar -cpsj --exclude /web/service0/etc/daemontools/supervise --file /tmp/service0-backup.tar.bz2 /web/service0/ tar: Removing leading `/' from member names -[service0@yourserver service0]$
On a test service, make sure that your backup-recovery process work. After backing up the database and file system, delete the service as detailed below and then recover it.
[root@yourserver root]# svc -d /service/service0 -[root@yourserver root]# mv /web/service0/ /web/service0.lost -[root@yourserver root]# rm /service/service0 +[service0@yourserver service0]$
On a test service, make sure that your backup-recovery process work. After backing up the database and file system, delete the service as detailed below and then recover it.
[root@yourserver root]# svc -d /service/service0 +[root@yourserver root]# mv /web/service0/ /web/service0.lost +[root@yourserver root]# rm /service/service0 rm: remove symbolic link `/service/service0'? y -[root@yourserver root]# ps -auxw | grep service0 +[root@yourserver root]# ps -auxw | grep service0 root 1496 0.0 0.0 1312 252 ? S 16:58 0:00 supervise service0 -[root@yourserver root]# kill 1496 -[root@yourserver root]# ps -auxw | grep service0 -[root@yourserver root]# su - postgres -[postgres@yourserver pgsql]$ dropdb service0 +[root@yourserver root]# kill 1496 +[root@yourserver root]# ps -auxw | grep service0 +[root@yourserver root]# su - postgres +[postgres@yourserver pgsql]$ dropdb service0 DROP DATABASE -[postgres@yourserver pgsql]$ dropuser service0 +[postgres@yourserver pgsql]$ dropuser service0 DROP USER -[postgres@yourserver pgsql]$ exit +[postgres@yourserver pgsql]$ exit logout -[root@yourserver root]#
Restore the operating system and required software. +[root@yourserver root]#
Restore the operating system and required software. You can do this with standard backup processes or by keeping copies of the install material (OS CDs, OpenACS - tarball and supporting software) and repeating the install guide.
Restore the OpenACS service. Assuming the user already exists, restore the database and files from backup and restore the daemontools link. (Because of a bug in Postgres backup-recovery, not all database objects are created in the correct order. To compensate, pre-creating some objects usually work.)
[root@yourserver root]# su - postgres
-[postgres@yourserver pgsql]$ createuser service0
-Shall the new user be allowed to create databases? (y/n) y
-Shall the new user be allowed to create more new users? (y/n) y
+ tarball and supporting software) and repeating the install guide.
Restore the OpenACS service. Assuming the user already exists, restore the database and files from backup and restore the daemontools link. (Because of a bug in Postgres backup-recovery, not all database objects are created in the correct order. To compensate, pre-creating some objects usually work.)
[root@yourserver root]# su - postgres +[postgres@yourserver pgsql]$ createuser service0 +Shall the new user be allowed to create databases? (y/n) y +Shall the new user be allowed to create more new users? (y/n) y CREATE USER -[postgres@yourserver pgsql]$ exit +[postgres@yourserver pgsql]$ exit logout -[root@yourserver root]# su - service0 -[service0@yourserver service0]$ cd /web -[service0@yourserver web]$ tar xjf /tmp/service0-backup.tar.bz2 -[service0@yourserver web]$ chmod -R 700 service0 -[service0@yourserver web]$ createdb service0 +[root@yourserver root]# su - service0 +[service0@yourserver service0]$ cd /web +[service0@yourserver web]$ tar xjf /tmp/service0-backup.tar.bz2 +[service0@yourserver web]$ chmod -R 700 service0 +[service0@yourserver web]$ createdb service0 CREATE DATABASE -[service0@yourserver web]$ psql -f /web/service0/packages/acs-kernel/sql/postgresql/postgresql.sql service0 +[service0@yourserver web]$ psql -f /web/service0/packages/acs-kernel/sql/postgresql/postgresql.sql service0 (many lines omitted) -[service0@yourserver web]$ psql service0 < /web/service0/database-backup/database-backup.dmp +[service0@yourserver web]$ psql service0 < /web/service0/database-backup/database-backup.dmp (many lines omitted) -[service0@yourserver web]$ exit -[root@yourserver root]# ln -s /web/service0/etc/daemontools /service/service0 -[root@yourserver root]# sleep 10 -[root@yourserver root]# svgroup web /service/service0 -[root@yourserver root]#
Earlier strategies, included here because this section - hasn't been fully updated yet.
Earlier strategies, included here because this section + hasn't been fully updated yet.
(This has not yet been updated to fit with the Reference install. To do so, edit the backup script to save the backup - file in /web/servicename/database-backup). + file in /web/servicename/database-backup). While you're working with Oracle, you should configure it to do automatic exports. An export is a separate backup copy of the database. This copy includes all of the database's state at the time that the export was initiated. If your database is corrupted, you can restore from one of these backups. You should do this step as - root. + root.
Download the backup script. Save the file export-oracle.txt as - /tmp/export-oracle.txt + /tmp/export-oracle.txt
Login as root. The following commands will install the export script:
@@ -110,18 +110,18 @@ root:~# chmod 700 /usr/sbin/export-oracle
Setup the export directory; this is the directory where backups will be stored. We recommend the directory - /ora8/m02/oracle-exports.
+ /ora8/m02/oracle-exports.root:~# mkdir /ora8/m02/oracle-exports root:~# chown oracle.dba /ora8/m02/oracle-exports root:~# chmod 770 /ora8/m02/oracle-exports
Now edit - /usr/sbin/export-oracle and - change the SERVICE_NAME and - DATABASE_PASSWORD fields to + /usr/sbin/export-oracle and + change the SERVICE_NAME and + DATABASE_PASSWORD fields to their correct values. If you want to use a directory other than - /ora8/m02/oracle-exports, you + /ora8/m02/oracle-exports, you also need to change the - exportdir setting. + exportdir setting.
Test the export procedure by running the command:
@@ -164,12 +164,12 @@ Export terminated successfully without warnings.
If you don't have any warnings, proceed to automate the backups.
Automating backups is accomplished using the UNIX - crontab facility.
- While still root, run the + crontab facility.
+ While still root, run the following command. You can replace the - EDITOR="emacs -nw" + EDITOR="emacs -nw" portion with whatever editor your prefer, such as - EDITOR=vi. + EDITOR=vi.
root:~# export EDITOR="emacs -nw" root:~# crontab -e
Now add the following line on a line by itself
@@ -179,32 +179,32 @@ root:~# crontab -l | grep export-oracle 0 23 * * * /usr/sbin/export-oracle root:~# exit -; Logout
If you see the line, go ahead and log out.
(This is not required for the Reference install.) Dowload this script - to /tmp. At the top of the script + to /tmp. At the top of the script are several variables that you'll need to customize:
- bak - location where you want + bak - location where you want local backups to be saved
- servername - name of your server + servername - name of your server (and database instance)
- ftp_user - username on your ftp + ftp_user - username on your ftp account
- ftp_password - password on your + ftp_password - password on your ftp account
- ftp_dir - path on the remote + ftp_dir - path on the remote server where your backups will be uploaded
- ftp_server - your ftp server + ftp_server - your ftp server
Next, we'll save this file to our server's - tcl directory so that it will be + tcl directory so that it will be loaded on startup. It will automatically be run every night at midnight. Note that this script only backs up the database - not the OpenACS scripts and file content. Index: openacs-4/packages/acs-core-docs/www/bootstrap-acs.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/bootstrap-acs.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/bootstrap-acs.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/bootstrap-acs.html 7 May 2003 17:40:58 -0000 1.8.2.9 @@ -1,90 +1,90 @@ -
+
by Jon Salz
OpenACS docs are written by the named authors, and may be edited
by OpenACS documentation staff.
Tcl code: /tcl/0-acs-init.tcl and /packages/acs-kernel/bootstrap.tcl
This document describes the startup (bootstrapping) process for an AOLserver running OpenACS. -
+
Before OpenACS 3.3, the OpenACS startup process was extremely simple: after AOLserver performed its internal initialization (reading the configuration file, loading shared libraries and module code, etc.) it scanned through the Tcl -library directory (generally /web/yourservername/tcl), +library directory (generally /web/yourservername/tcl), sourcing each file in sequence.
While this overall structure for initialization is still intact, package management has thrown a wrench into the works - there are a few extra things to do during initialization, most notably:
Examine the OpenACS file tree for files that should not be present in OpenACS (i.e., that were once part of the OpenACS distribution but have since been -removed).
Scan the /packages directory for new packages.
Initialize enabled packages by sourcing their *-procs.tcl -and *-init.tcl files.
+removed).
Scan the /packages directory for new packages.
Initialize enabled packages by sourcing their *-procs.tcl +and *-init.tcl files.
This document examines in detail each of the steps involved in AOLserver/OpenACS startup. -
+As soon as the nsd daemon is executed by the init process (or otherwise), AOLserver reads its configuration file and -chroots itself if necessary. It then loads shared libraries -indicated in the .ini file (e.g., the Oracle driver and -nssock), and sources Tcl module files (generally in -/home/aol30/modules/tcl). This step is, and has always been, the +chroots itself if necessary. It then loads shared libraries +indicated in the .ini file (e.g., the Oracle driver and +nssock), and sources Tcl module files (generally in +/home/aol30/modules/tcl). This step is, and has always been, the same for all AOLservers, regardless of whether they are running OpenACS.
Next AOLserver sources, in lexicographical order, each file in the -/tcl directory. The first such file is -0-acs-init.tcl, which doesn't do much directly except to -determine the OpenACS path root (e.g., /web/yourservername) +/tcl directory. The first such file is +0-acs-init.tcl, which doesn't do much directly except to +determine the OpenACS path root (e.g., /web/yourservername) by trimming the final component from the path to the Tcl library directory -(/web/yourservername/tcl). But -0-acs-init.tcl's has an important function, namely sourcing -/packages/acs-core/bootstrap.tcl, which does the following:
Initialize some NSVs used by the core. These NSVs are -documented in /packages/acs-core/apm-procs.tcl - no need to +(/web/yourservername/tcl). But +0-acs-init.tcl's has an important function, namely sourcing +/packages/acs-core/bootstrap.tcl, which does the following:
Initialize some NSVs used by the core. These NSVs are +documented in /packages/acs-core/apm-procs.tcl - no need to worry about them unless you're an OpenACS core hacker.
Verify the deletion of obsolete OpenACS files. The -/tcl directory has evolved quite a bit over the months and +/tcl directory has evolved quite a bit over the months and years, and a few files have come and gone. The -/www/doc/removed-files.txt file contains a list of files which +/www/doc/removed-files.txt file contains a list of files which must be deleted from the AOLserver installation, at the risk of causing weird conflicts, e.g., having several security filters registered. -bootstrap.tcl scans through this list, logging error messages to +bootstrap.tcl scans through this list, logging error messages to the log if any of these files exist. -
Source *-procs.tcl files in the OpenACS core. -We source each file matching the *-procs.tcl glob in the -/packages/acs-kernel directory, in lexicographical order. These +
Source *-procs.tcl files in the OpenACS core. +We source each file matching the *-procs.tcl glob in the +/packages/acs-kernel directory, in lexicographical order. These procedure are needed to perform any of the following steps.
Ensure that the database is available by grabbing and releasing a handle. If we can't obtain a handle, we terminate initialization (since OpenACS couldn't possibly start up the server without access to the database). -
Register any new packages in the /packages -directory. In each directory inside /packages, we look -for a .info file; if we find a package that hasn't yet been +
Register any new packages in the /packages +directory. In each directory inside /packages, we look +for a .info file; if we find a package that hasn't yet been registered with the package manager (i.e., it's been copied there manually), we insert information about it into the database. (The first time OpenACS starts up, no packages will have been registered in the database yet, so this step will registers every single package in the -/packages directory.) Note that packages discovered here are +/packages directory.) Note that packages discovered here are initially disabled; they must be manually enabled in the package manager before they can be used. -
Ensure that the acs-kernel package is +
Ensure that the acs-kernel package is enabled. If the OpenACS core isn't initialized, the server couldn't possibly be operational, so if there's no enabled version of the OpenACS core we simply mark the latest installed one as enabled. -
Load *-procs.tcl files for enabled +
Load *-procs.tcl files for enabled packages, activating their APIs. -
Load *-init.tcl files for enabled packages, +
Load *-init.tcl files for enabled packages, giving packages a chance to register filters and procedures, initialize data structures, etc.
Verify that the core has been properly initialized by checking for the existence of an NSV created by the request processor initialization code. If it's not present, the server won't be operational, so we log an error.
-At this point, bootstrap.tcl is done executing. AOLserver -proceeds to source the remaining files in the /tcl directory +At this point, bootstrap.tcl is done executing. AOLserver +proceeds to source the remaining files in the /tcl directory (i.e., unpackaged libraries) and begins listening for connections.
+
by Vinod Kurup
OpenACS docs are written by the named authors, and may be edited
by OpenACS documentation staff.
Index: openacs-4/packages/acs-core-docs/www/database-management.html
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/database-management.html,v
diff -u -r1.1.2.7 -r1.1.2.8
--- openacs-4/packages/acs-core-docs/www/database-management.html 4 May 2003 06:30:02 -0000 1.1.2.7
+++ openacs-4/packages/acs-core-docs/www/database-management.html 7 May 2003 17:40:58 -0000 1.1.2.8
@@ -1,13 +1,13 @@
-
+
by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited
by OpenACS documentation staff.
-
Skip down for instructions on Deleting a PostgreSQL tablespace. -
Skip down for instructions on Deleting a PostgreSQL tablespace. +
Should it become necessary to rebuild a tablespace from scratch, - you can use the drop user command - in SVRMGRL with the cascade + you can use the drop user command + in SVRMGRL with the cascade option. This command will drop the user and every database object the user owns.
SVRMGR> drop user service0 cascade;
@@ -20,17 +20,17 @@ replaced with the corresponding values for the open session.
Use with caution!
If you feel the need to delete everything related to the service, you can also issue the following:
-SVRMGR> drop tablespace service0 including contents cascade constraints;
+SVRMGR> drop tablespace service0 including contents cascade constraints;
Dropping a PostgreSQL tablespace is easy. You have to stop any AOLserver instances that are using the database that you wish to drop. If you're using daemontools, this is simple, just use the 'down' flag (-d). If you're using inittab, you have to comment out - your server in /etc/inittab, - reread the inittab with /sbin/init - q, and then restart-aolserver + your server in /etc/inittab, + reread the inittab with /sbin/init + q, and then restart-aolserver service0.
Then, to drop the db, just do:
service0:~$ dropdb service0
-DROP DATABASE
The "vacuum" command must be run periodically to reclaim space. The "vacuum analyze" form additionally collects statistics on the disbursion of columns in the database, which the optimizer uses when Index: openacs-4/packages/acs-core-docs/www/db-api-detailed.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/db-api-detailed.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/db-api-detailed.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/db-api-detailed.html 7 May 2003 17:40:58 -0000 1.8.2.9 @@ -1,26 +1,26 @@ -
+
by Jon Salz. Revised and expanded by
Roberto Mello (rmello at fslc dot usu dot edu), July 2002.
OpenACS docs are written by the named authors, and may be edited
by OpenACS documentation staff.
-
Tcl procedures: /packages/acs-kernel/10-database-procs.tcl
Tcl initialization: /packages/acs-kernel/database-init.tcl
Tcl procedures: /packages/acs-kernel/10-database-procs.tcl
Tcl initialization: /packages/acs-kernel/database-init.tcl
One of OpenACS's great strengths is that code written for it is very close to the database. It is very easy to interact with the database from anywhere within OpenACS. Our goal is to develop a coherent API for database access which makes this even easier.
There were four significant problems with the way OpenACS previously used the -database (i.e., directly through the ns_db interface):
Handle management. We required code to pass database +database (i.e., directly through the ns_db interface):
Handle management. We required code to pass database handles around, and for routines which needed to perform database access but didn't receive a database handle as input, it was difficult to know from which of the three "magic pools" (main, subquery, and log) to allocate a new handle. -
Nested transactions. In our Oracle driver, begin +
Nested transactions. In our Oracle driver, begin transaction really means "turn auto-commit mode off" and -end transaction means "commit the current transaction and +end transaction means "commit the current transaction and turn auto-commit mode on." Thus if transactional code needed to call a routine which needed to operate transactionally, the semantics were non-obvious. Consider:
@@ -38,8 +38,8 @@ }
-This would insert greeble #33 and do all the stuff in foo -transactionally, but the end transaction in foo +This would insert greeble #33 and do all the stuff in foo +transactionally, but the end transaction in foo would actually cause a commit, and greeble #50 would later be inserted in auto-commit mode. This could cause subtle bugs: e.g., in the case that the insert for greeble #50 failed, part of the "transaction" would have @@ -48,15 +48,15 @@
Unorthodox use of variables. The standard mechanism for mapping column values into variables involved the use of the -set_variables_after_query routine, which relies on an uplevel -variable named selection (likewise for -set_variables_after_subquery and subselection). +set_variables_after_query routine, which relies on an uplevel +variable named selection (likewise for +set_variables_after_subquery and subselection).
Hard-coded reliance on Oracle. It's difficult to write code supporting various different databases (dynamically using the appropriate dialect based on the type of database being used, e.g., using -DECODE on Oracle and CASE ... WHEN on +DECODE on Oracle and CASE ... WHEN on Postgres).
The Database Access API addresses the first three problems by:
making use of database handles transparent
wrapping common database operations (including transaction management) in @@ -70,9 +70,9 @@
To be clear, SQL abstraction is not fully implemented in OpenACS 3.3.1. The statement names supplied to each call are not used by the API at all. The API's design for SQL abstraction is in fact incomplete; -unresolved issues include:
how to add WHERE clause criteria dynamically
how to build a dynamic ORDER BY clause (Ben Adida has a +unresolved issues include:
how to add WHERE clause criteria dynamically
how to build a dynamic ORDER BY clause (Ben Adida has a proposed solution for this)
how to define a statement's formal interface (i.e., what bind -variables it expects, what columns its SELECT clause must +variables it expects, what columns its SELECT clause must contain if it's a query) without actually implementing the statement in a specific SQL dialect
So why is the incremental change of adding statement naming to the API worth @@ -81,8 +81,8 @@ design. Therefore, we know that the effort will not be wasted, and taking advantage of the new support for bind variables will already require code that uses 3.3.0 version of the API to be updated. -
-set_variables_after_query is gone! (Well, it's still there, +
+set_variables_after_query is gone! (Well, it's still there, but you'll never need to use it.) The new API routines set local variables automatically. For instance:
@@ -91,7 +91,7 @@ doc_body_append "Hello, $first_names $last_name!"
-Like ns_db 1row, this will bomb if the query doesn't return +Like ns_db 1row, this will bomb if the query doesn't return any rows (no such user exists). If this isn't what you want, you can write:
@@ -113,9 +113,9 @@ }
-That's right, db_foreach is now like ns_db -select plus a while loop plus -set_variables_after_query plus an if statement +That's right, db_foreach is now like ns_db +select plus a while loop plus +set_variables_after_query plus an if statement (containing code to be executed if no rows are returned).
@@ -126,7 +126,7 @@ doc_body_append "There aren't any users with last names beginnings with S!" } -
The new API keeps track of which handles are in use, and automatically allocates new handles when they are necessary (e.g., to perform subqueries while a select is active). For example: @@ -152,10 +152,10 @@
A new handle isn't actually allocated and released for every selection, of course - as a performance optimization, the API keeps old handles around -until db_release_unused_handles is invoked (or the script +until db_release_unused_handles is invoked (or the script terminates). -
Note that there is no analogue to ns_db gethandle - the -handle is always automatically allocated the first time it's needed.
Introduction
+
Note that there is no analogue to ns_db gethandle - the +handle is always automatically allocated the first time it's needed.
Introduction
Most SQL statements require that the code invoking the statement pass along data associated with that statement, usually obtained from the user. For instance, in order to delete a WimpyPoint presentation, a Tcl script might @@ -165,7 +165,7 @@ delete from wp_presentations where presentation_id = some_presentation_id
-where some_presentation_id is a number which is a valid +where some_presentation_id is a number which is a valid presentation ID of the presentation I want to delete. It's easy to write code handling situations like this since SQL statements can include bind variables, which represent placeholders for actual @@ -179,15 +179,15 @@
When this SQL statement is invoked, the value for the bind variable -:some_presentation_id is pulled from the Tcl variable -$some_presentation_id (in the caller's environment). Note +:some_presentation_id is pulled from the Tcl variable +$some_presentation_id (in the caller's environment). Note that bind variables are not limited to one per statement; you can use an arbitrary number, and each will pull from the correspondingly named Tcl -variable. (Alternatively, you can also specify an list or ns_set +variable. (Alternatively, you can also specify an list or ns_set providing bind variables' values; see Usage.)
The value of a bind variable is taken literally by the database driver, so there is never any need to put single-quotes around the value for a bind -variable, or to use db_quote to escape single-quotes contained +variable, or to use db_quote to escape single-quotes contained in the value. The following works fine, despite the apostrophe:
set exclamation "That's all, folks!" @@ -196,7 +196,7 @@
Note that you can use a bind variable in a SQL statement only where you could use a literal (a number or single-quoted string). Bind variables cannot be placeholders for things like SQL keywords, table names, or column names, -so the following will not work, even if $table_name is set +so the following will not work, even if $table_name is set properly:
select * from :table_name @@ -212,9 +212,9 @@
(Note the use of double-quotes to allow the variable reference to -$some_presentation_id to be interpolated in.) This will work, +$some_presentation_id to be interpolated in.) This will work, but consider the case where some devious user causes -some_presentation_id to be set to something like '3 or +some_presentation_id to be set to something like '3 or 1 = 1', which would result in the following statement being executed:
@@ -225,18 +225,18 @@ This deletes every presentation in the database! Using bind variables eliminates this gaping security hole: since bind variable values are taken literally. Oracle will attempt to delete presentations whose presentation ID -is literally '3 or 1 = 1' (i.e., no presentations, since -'3 or 1 = 1' can't possibly be a valid integer -primary key for wp_presentations. In general, since Oracle +is literally '3 or 1 = 1' (i.e., no presentations, since +'3 or 1 = 1' can't possibly be a valid integer +primary key for wp_presentations. In general, since Oracle always considers the values of bind variables to be literals, it becomes more difficult for users to perform URL surgery to trick scripts into running dangerous queries and DML. -Usage
Every db_* command accepting a SQL command as an argument -supports bind variables. You can either
specify the -bind switch to provide a set with bind variable -values, or
specify the -bind switch to explicitly provide a list of +
Usage
Every db_* command accepting a SQL command as an argument +supports bind variables. You can either
specify the -bind switch to provide a set with bind variable +values, or
specify the -bind switch to explicitly provide a list of bind variable names and values, or
not specify a bind variable list at all, in which case Tcl variables are used as bind variables.
-The default behavior (i.e., if the -bind switch is omitted) is +The default behavior (i.e., if the -bind switch is omitted) is that these procedures expect to find local variables that correspond in name to the referenced bind variables, e.g.:
@@ -256,9 +256,9 @@ }-The value of the local Tcl variable user_id (123456) is bound to -the user_id bind variable. -
The -bind switch can takes the name of an ns_set +The value of the local Tcl variable user_id (123456) is bound to +the user_id bind variable. +
The -bind switch can takes the name of an ns_set containing keys for each bind variable named in the query, e.g.:
set bind_vars [ns_set create] @@ -277,7 +277,7 @@ }-Alternatively, as an argument to -bind you can specify a list of +Alternatively, as an argument to -bind you can specify a list of alternating name/value pairs for bind variables:
@@ -294,12 +294,12 @@When processing a DML statement, Oracle coerces empty strings into -null. (This coercion does not occur in the -WHERE clause of a query, i.e. -col = '' and -col is null are not equivalent.) +null. (This coercion does not occur in the +WHERE clause of a query, i.e. +col = '' and +col is null are not equivalent.)
As a result, when using bind variables, the only way to make Oracle set a -column value to null is to set the corresponding bind variable +column value to null is to set the corresponding bind variable to the empty string, since a bind variable whose value is the string "null" will be interpreted as the literal string "null".
These Oracle quirks complicate the process of writing clear and abstract @@ -325,13 +325,13 @@
Since databases other than Oracle do not coerce empty strings into -null, this code has different semantics depending on the +null, this code has different semantics depending on the underlying database (i.e., the row that gets inserted may not have null as its column values), which defeats the purpose of SQL abstraction.
Therefore, the Database Access API provides a database-independent way to -represent null (instead of the Oracle-specific idiom of the -empty string): db_null.
Use it instead of the empty string whenever you want to set a column value -explicitly to null, e.g.:
+represent null (instead of the Oracle-specific idiom of the +empty string): db_null.Use it instead of the empty string whenever you want to set a column value +explicitly to null, e.g.:
set bar [db_null] set baz [db_null] @@ -340,15 +340,15 @@ # # sets the values for both the "bar" and "baz" columns to null -We now require that each SQL statement be assigned a logical name for the statement that is unique to the procedure or page in which it is defined. This is so that (eventually) we can implement logically named statements with alternative SQL for non-Oracle databases (e.g., Postgres). More on this later. -
-Normally, db_foreach, db_0or1row, and -db_1row places the results of queries in Tcl variables, so you +
+Normally, db_foreach, db_0or1row, and +db_1row places the results of queries in Tcl variables, so you can say:
@@ -360,10 +360,10 @@ However, sometimes this is not sufficient: you may need to examine the rows returned, to dynamically determine the set of columns returned by the query, or to avoid collisions with existing variables. You can use the --column_array and -column_set switches to -db_foreach, db_0or1row, and db_1row to +-column_array and -column_set switches to +db_foreach, db_0or1row, and db_1row to instruct the database routines to place the results in a Tcl array or -ns_set, respectively, where the keys are the column names and +ns_set, respectively, where the keys are the column names and the values are the column values. For example:@@ -377,28 +377,28 @@will write something like: -
first_names is Jon. last_name is Salz.
first_names is Lars. last_name is Pind.
first_names is Michael. last_name is Yoon.
-Note that you never have to use ns_db anymore (including -ns_db gethandle)! Just start doing stuff, and (if you want) call -db_release_unused_handles when you're done as a hint to +
first_names is Jon. last_name is Salz.
first_names is Lars. last_name is Pind.
first_names is Michael. last_name is Yoon.
+Note that you never have to use ns_db anymore (including +ns_db gethandle)! Just start doing stuff, and (if you want) call +db_release_unused_handles when you're done as a hint to release the database handle. -
- db_null +
- db_null
-db_null +db_nullReturns a value which can be used in a bind variable to represent the SQL -value null. See Nulls and Bind Variables +value null. See Nulls and Bind Variables above.
- -db_foreach +db_foreach
db_foreach statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ [ -column_array array_name | -column_set set_name ] \ code_block [ if_no_rows if_no_rows_block ] -Performs the SQL query sql, executing -code_block once for each row with variables set to -column values (or a set or array populated if -column_array or -column_set is specified). If the query returns no rows, executes -if_no_rows_block (if provided).
Example:
+Performs the SQL query sql, executing +code_block once for each row with variables set to +column values (or a set or array populated if -column_array or +column_set is specified). If the query returns no rows, executes +if_no_rows_block (if provided).
Example:
db_foreach select_foo "select foo, bar from greeble" { doc_body_append "<li>foo=$foo; bar=$bar\n" @@ -407,72 +407,72 @@ }-The code block may contain break statements (which terminate the -loop and flush the database handle) and continue statements -(which continue to the next row of the loop).
- db_1row
+The code block may contain break statements (which terminate the +loop and flush the database handle) and continue statements +(which continue to the next row of the loop).- db_1row
db_1row statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ [ -column_array array_name | -column_set set_name ] -Performs the SQL query sql, setting variables to +
Performs the SQL query sql, setting variables to column values. Raises an error if the query does not return exactly 1 row.
Example:
db_1row select_foo "select foo, bar from greeble where greeble_id = $greeble_id" # Bombs if there's no such greeble! # Now $foo and $bar are set. -- db_0or1row
+- db_0or1row
db_0or1row statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ [ -column_array array_name | -column_set set_name ] -Performs the SQL query sql. If a row is returned, +
Performs the SQL query sql. If a row is returned, sets variables to column values and returns 1. If no rows are returned, -returns 0. If more than one row is returned, throws an error.
- db_string
+returns 0. If more than one row is returned, throws an error.- db_string
db_string statement-name sql [ -default default ] [ -bind bind_set_id | -bind bind_value_list ]Returns the first column of the result of SQL query -sql. If sql doesn't return a -row, returns default (or throws an error if -default is unspecified). Analogous to -database_to_tcl_string and -database_to_tcl_string_or_null. +sql. If sql doesn't return a +row, returns default (or throws an error if +default is unspecified). Analogous to +database_to_tcl_string and +database_to_tcl_string_or_null. -
- db_nextval
+- db_nextval
db_nextval sequence-nameReturns the next value for the sequence sequence-name (using a -SQL statement like SELECT sequence-name.nextval FROM +SQL statement like SELECT sequence-name.nextval FROM DUAL). If sequence pooling is enabled for the sequence, transparently uses a value from the pool if available to save a round-trip to the database. -
- db_list
+- db_list
db_list statement-name sql [ -bind bind_set_id | -bind bind_value_list ]Returns a Tcl list of the values in the first column of the result of SQL -query sql. If sql doesn't +query sql. If sql doesn't return any rows, returns an empty list. Analogous to -database_to_tcl_list. +database_to_tcl_list. -
- db_list_of_lists
+- db_list_of_lists
db_list_of_lists statement-name sql [ -bind bind_set_id | -bind bind_value_list ]Returns a Tcl list, each element of which is a list of all column values -in a row of the result of SQL query sql. If -sql doesn't return any rows, returns an empty list. -(Analogous to database_to_tcl_list_list.) +in a row of the result of SQL query sql. If +sql doesn't return any rows, returns an empty list. +(Analogous to database_to_tcl_list_list.) -
- db_list_of_ns_sets
+- db_list_of_ns_sets
db_list_of_ns_sets statement-name sql [ -bind bind_set_id | -bind bind_value_list ]Returns a list of ns_sets with the values of each column of each row - returned by the sql query specified. -
- db_dml
+ returned by the sql query specified. +- db_dml
db_dml statement-name sql \ [ -bind bind_set_id | -bind bind_value_list ] \ [ -blobs blob_list | -clobs clob_list | -blob_files blob_file_list | -clob_files clob_file_list ] -Performs the DML or DDL statement sql.
If a length-n list of blobs or clobs is provided, then the SQL +
Performs the DML or DDL statement sql.
If a length-n list of blobs or clobs is provided, then the SQL should return n blobs or clobs into the bind variables -:1, :2, ... :n. -blobs or clobs, if specified, +:1, :2, ... :n. +blobs or clobs, if specified, should be a list of individual BLOBs or CLOBs to insert; -blob_files or clob_files, if +blob_files or clob_files, if specified, should be a list of paths to files containing the data to -insert. Only one of -blobs, -clobs, --blob_files, and -clob_files may be provided.
Example:
+insert. Only one of -blobs, -clobs, +-blob_files, and -clob_files may be provided.Example:
db_dml insert_photos " insert photos(photo_id, image, thumbnail_image) @@ -481,37 +481,37 @@ " -blob_files [list "/var/tmp/the_photo" "/var/tmp/the_thumbnail"]-This inserts a new row into the photos table, with the contents -of the files /var/tmp/the_photo and -/var/tmp/the_thumbnail in the image and -thumbnail columns, respectively. +This inserts a new row into the photos table, with the contents +of the files /var/tmp/the_photo and +/var/tmp/the_thumbnail in the image and +thumbnail columns, respectively.
- -db_write_clob, -db_write_blob, -db_blob_get_file +db_write_clob, +db_write_blob, +db_blob_get_file
db_write_clob statement-name sql [ -bind bind_set_id | -bind bind_value_list ] db_write_blob statement-name sql [ -bind bind_set_id | -bind bind_value_list ] db_blob_get_file statement-name sql [ -bind bind_set_id | -bind bind_value_list ] -Analagous to ns_ora write_clob/write_blob/blob_get_file. +
Analagous to ns_ora write_clob/write_blob/blob_get_file. -
- db_release_unused_handles
+- db_release_unused_handles
db_release_unused_handles -
Releases any allocated, unused database handles.
- db_transaction
+Releases any allocated, unused database handles.
- db_transaction
db_transaction code_block [ on_error { code_block } ] -Executes code_block transactionally. Nested -transactions are supported (end transaction is transparently -ns_db dml'ed when the outermost transaction completes). The -db_abort_transaction command can be used to abort all levels of -transactions. It is possible to specify an optional on_error +
Executes code_block transactionally. Nested +transactions are supported (end transaction is transparently +ns_db dml'ed when the outermost transaction completes). The +db_abort_transaction command can be used to abort all levels of +transactions. It is possible to specify an optional on_error code block that will be executed if some code in code_block throws -an exception. The variable errmsg will be bound in that scope. -If there is no on_error code, any errors will be propagated.
Example:
+an exception. The variable errmsg will be bound in that scope. +If there is no on_error code, any errors will be propagated.Example:
proc replace_the_foo { col } { db_transaction { @@ -540,33 +540,33 @@ print_the_foo ; # Writes out "foo is 8" -- db_abort_transaction +
- db_abort_transaction
db_abort_transaction
Aborts all levels of a transaction. That is if this is called within several nested transactions, all of them are terminated. Use this insetead of -db_dml "abort" "abort transaction". +db_dml "abort" "abort transaction". -
- db_multirow
+- db_multirow
db_multirow [ -local ] [ -append ] [ -extend column_list ] \ var-name statement-name sql \ [ -bind bind_set_id | -bind bind_value_list ] \ code_block [ if_no_rows if_no_rows_block ]- Performs the SQL query sql, saving results in variables + Performs the SQL query sql, saving results in variables of the form - var_name:1, var_name:2, etc, - setting var_name:rowcount to the total number - of rows, and setting var_name:columns to a + var_name:1, var_name:2, etc, + setting var_name:rowcount to the total number + of rows, and setting var_name:columns to a list of column names.
Each row also has a column, rownum, automatically added and set to the row number, starting with 1. Note that this will override any column in the SQL statement named 'rownum', also if you're using the Oracle rownum pseudo-column.
- If the -local is passed, the variables defined + If the -local is passed, the variables defined by db_multirow will be set locally (useful if you're compiling dynamic templates in a function or similar situations).
@@ -579,19 +579,19 @@ multirow.
You may also add additional, computed columns to the multirow, using the - -extend { col_1 col_2 ... } switch. This is + -extend { col_1 col_2 ... } switch. This is useful for things like constructing a URL for the object retrieved by the query.
If you're constructing your multirow through multiple queries with the same set of columns, but with different rows, you can use the - -append switch. This causes the rows returned by this query + -append switch. This causes the rows returned by this query to be appended to the rows already in the multirow, instead of starting a clean multirow, as is the normal behavior. The columns must match the columns in the original multirow, or an error will be thrown.
- Your code block may call continue in order to skip a row - and not include it in the multirow. Or you can call break + Your code block may call continue in order to skip a row + and not include it in the multirow. Or you can call break to skip this row and quit looping.
@@ -606,18 +606,18 @@ } { set user_url [acs_community_member_url -user_id $user_id] } -
- db_resultrows
+- db_resultrows
db_resultrows
Returns the number of rows affected or returned by the previous statement. -
- db_with_handle
+- db_with_handle
db_with_handle var code_block -Places a database handle into the variable var and -executes code_block. This is useful when you don't -want to have to use the new API (db_foreach, -db_1row, etc.), but need to use database handles explicitly.
Example:
+Places a database handle into the variable var and +executes code_block. This is useful when you don't +want to have to use the new API (db_foreach, +db_1row, etc.), but need to use database handles explicitly.
Example:
proc lookup_the_foo { foo } { db_with_handle db { @@ -637,32 +637,32 @@- - + db_name
- db_name + db_name
Returns the name of the database, as returned by the driver.
- - + db_type
- db_type + db_type
Returns the RDBMS type (i.e. oracle, postgresql) this OpenACS installation is using. The nsv ad_database_type is set up during the bootstrap process.
- - + db_compatible_rdbms_p @@ -672,7 +672,7 @@ Returns 1 if the given db_type is compatible with the current RDBMS.
- - + db_package_supports_rdbms_p @@ -684,7 +684,7 @@ file regardless of whether or not it actually uses the database.
- - + db_legacy_package_p @@ -695,7 +695,7 @@ it explicitly supports Oracle 8.1.6 rather than the OpenACS more general oracle.
- - + db_version @@ -706,7 +706,7 @@ recent PostgreSQL version.
- - + db_current_rdbms @@ -716,7 +716,7 @@ Returns the current rdbms type and version.
- - + db_known_database_types Index: openacs-4/packages/acs-core-docs/www/db-api.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/db-api.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/db-api.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/db-api.html 7 May 2003 17:40:58 -0000 1.8.2.9 @@ -1,17 +1,17 @@ -
The OpenACS Database Access API +
The OpenACS Database Access API By Pete Su and Jon Salz. Modified by Roberto Mello. -
+
One of OpenACS's great strengths is that code written for it is very close to the database. It is very easy to interact with the database from anywhere within OpenACS. Our goal is to develop a coherent API for database access which makes this even easier.
More detailed information about the DB api is available at Database Access API. -
Here's a typical block of code from an OpenACS 3.x dynamic page:
set tcl_var "foo" @@ -53,7 +53,7 @@ from the page to the database, is error prone, relatively inefficient, and a good way to compromise the security of a web site.- Magic like set_variables_after_query made code confusing. + Magic like set_variables_after_query made code confusing.
The scope of transactions is not clear from reading the code.
@@ -66,7 +66,7 @@ Introduced in ACS 3.4, the new Database API is meant to save developers from the above tedium and provide a more structured syntax for specifying database operations, including transactions. -
Here is how you would code up the example above using the new API.
set count 0 @@ -97,13 +97,13 @@ No explicit code for grabbing and releasing handles. Usage of the Database API implicitly deals with all handle management issues.- The new command db_transaction + The new command db_transaction makes the scope of a transaction - clear. db_transaction takes the + clear. db_transaction takes the code block argument and automatically runs it in the context of a transaction.
- The new command db_foreach writes + The new command db_foreach writes our old while loop for us.
Every SQL query has a name, meant to be unique within the server @@ -113,7 +113,7 @@ from a Tcl variable to the database, which we'll cover next.
-
Bind variables are placeholders for literal values in an SQL query being sent to the server. Take the example query above: in the old way, data was generally passed to Oracle directly, via Tcl string @@ -235,18 +235,18 @@ Finally, the DB API has several different styles for passing bind variable values to queries. In general, use the style presented here because it is the most convenient. -
Every db_* command accepting a SQL command as an argument +
Every db_* command accepting a SQL command as an argument supports bind variables. You can either
- Specify the -bind switch to provide a set with bind variable + Specify the -bind switch to provide a set with bind variable values, or
- Specify the -bind switch to explicitly provide a list of + Specify the -bind switch to explicitly provide a list of bind variable names and values, or
Not specify a bind variable list at all, in which case Tcl variables are used as bind variables.
- The default behavior (i.e., if the -bind switch is omitted) is + The default behavior (i.e., if the -bind switch is omitted) is that these procedures expect to find local variables that correspond in name to the referenced bind variables, e.g.:
@@ -266,9 +266,9 @@ }- The value of the local Tcl variable user_id (123456) is bound to - the user_id bind variable. -
The -bind switch can takes the name of an ns_set + The value of the local Tcl variable user_id (123456) is bound to + the user_id bind variable. +
The -bind switch can takes the name of an ns_set containing keys for each bind variable named in the query, e.g.:
set bind_vars [ns_set create] @@ -287,7 +287,7 @@ }- Alternatively, as an argument to -bind you can specify a list of + Alternatively, as an argument to -bind you can specify a list of alternating name/value pairs for bind variables:
@@ -302,14 +302,14 @@ # of "administrator" } -When processing a DML statement, Oracle coerces empty strings into - null. (This coercion does not occur in the - WHERE clause of a query, i.e. - col = '' and - col is null are not equivalent.) + null. (This coercion does not occur in the + WHERE clause of a query, i.e. + col = '' and + col is null are not equivalent.)
As a result, when using bind variables, the only way to make Oracle set a - column value to null is to set the corresponding bind variable + column value to null is to set the corresponding bind variable to the empty string, since a bind variable whose value is the string "null" will be interpreted as the literal string "null".
These Oracle quirks complicate the process of writing clear and abstract @@ -335,13 +335,13 @@
Since databases other than Oracle do not coerce empty strings into - null, this code has different semantics depending on the + null, this code has different semantics depending on the underlying database (i.e., the row that gets inserted may not have null as its column values), which defeats the purpose of SQL abstraction.
Therefore, the Database Access API provides a database-independent way to - represent null (instead of the Oracle-specific idiom of the - empty string): db_null.
Use it instead of the empty string whenever you want to set a column value - explicitly to null, e.g.:
+ represent null (instead of the Oracle-specific idiom of the + empty string): db_null.Use it instead of the empty string whenever you want to set a column value + explicitly to null, e.g.:
set bar [db_null] set baz [db_null] @@ -350,21 +350,21 @@ # # sets the values for both the "bar" and "baz" columns to null -The database library can transparently maintain pools of sequence values, so - that each request for a new sequence value (using db_nextval) + that each request for a new sequence value (using db_nextval) does not incur a roundtrip to the server. For instance, this functionality is very useful in the security/sessions library, which very frequently allocates - values from the sec_id_seq sequence. To utilize this + values from the sec_id_seq sequence. To utilize this functionality for a particular sequence, register the sequence to be pooled, - either using the db_register_pooled_sequence procedure at server + either using the db_register_pooled_sequence procedure at server startup time, or by including a configuration parameter of the form
PoolSequence.sequence_name_seq=count- in any configuration section in the yourservername.ini + in any configuration section in the yourservername.ini file, e.g., e.g.,
@@ -376,49 +376,49 @@ startup. It will periodically scan pools and allocate new values for sequences which are less than half-full. (This normally occurs every 60 seconds, and is configurable via the - PooledSequenceUpdateInterval parameter in the - [ns/server/ - yourservername - /acs/database] configuration + PooledSequenceUpdateInterval parameter in the + [ns/server/ + yourservername + /acs/database] configuration section.) -The Database API has several functions that wrap familiar parts of the AOLserver database API.
- Note that you never have to use ns_db anymore (including - ns_db gethandle)! Just start doing stuff, and (if you want) call - db_release_unused_handles when you're done as a hint to + Note that you never have to use ns_db anymore (including + ns_db gethandle)! Just start doing stuff, and (if you want) call + db_release_unused_handles when you're done as a hint to release the database handle.
- - + db_abort_transaction
db_abort_transactionAborts all levels of a transaction. That is if this is called within several nested transactions, all of them are terminated. Use this insetead of - db_dml "abort" "abort transaction". + db_dml "abort" "abort transaction". -
- db_multirow
+- db_multirow
db_multirow [ -local ] [ -append ] [ -extend column_list ] \ var-name statement-name sql \ [ -bind bind_set_id | -bind bind_value_list ] \ code_block [ if_no_rows if_no_rows_block ]- Performs the SQL query sql, saving results in variables + Performs the SQL query sql, saving results in variables of the form - var_name:1, var_name:2, etc, - setting var_name:rowcount to the total number - of rows, and setting var_name:columns to a + var_name:1, var_name:2, etc, + setting var_name:rowcount to the total number + of rows, and setting var_name:columns to a list of column names.
Each row also has a column, rownum, automatically added and set to the row number, starting with 1. Note that this will override any column in the SQL statement named 'rownum', also if you're using the Oracle rownum pseudo-column.
- If the -local is passed, the variables defined + If the -local is passed, the variables defined by db_multirow will be set locally (useful if you're compiling dynamic templates in a function or similar situations).
@@ -431,19 +431,19 @@ multirow.
You may also add additional, computed columns to the multirow, using the - -extend { col_1 col_2 ... } switch. This is + -extend { col_1 col_2 ... } switch. This is useful for things like constructing a URL for the object retrieved by the query.
If you're constructing your multirow through multiple queries with the same set of columns, but with different rows, you can use the - -append switch. This causes the rows returned by this query + -append switch. This causes the rows returned by this query to be appended to the rows already in the multirow, instead of starting a clean multirow, as is the normal behavior. The columns must match the columns in the original multirow, or an error will be thrown.
- Your code block may call continue in order to skip a row - and not include it in the multirow. Or you can call break + Your code block may call continue in order to skip a row + and not include it in the multirow. Or you can call break to skip this row and quit looping.
@@ -460,22 +460,22 @@ }
- - + db_null
-db_null +db_nullReturns a value which can be used in a bind variable to represent the SQL value - null. + null. See Nulls and Bind Variables above.
- - + db_foreach @@ -485,16 +485,16 @@ code_block [ if_no_rows if_no_rows_block ]
Performs the SQL query - sql + sql , executing - code_block + code_block once for each row with variables set to column values (or a set or array populated if - -column_array or - column_set is + -column_array or + column_set is specified). If the query returns no rows, executes - if_no_rows_block + if_no_rows_block (if provided).
Example:
@@ -505,11 +505,11 @@ }- The code block may contain break statements (which terminate the - loop and flush the database handle) and continue statements + The code block may contain break statements (which terminate the + loop and flush the database handle) and continue statements (which continue to the next row of the loop).
- - + db_1row @@ -518,7 +518,7 @@ [ -column_array array_name | -column_set set_name ]
Performs the SQL query - sql, + sql
, setting variables to column values. Raises an error if the query does not return exactly 1 row.Example:
@@ -529,7 +529,7 @@- - + db_0or1row @@ -538,22 +538,22 @@ [ -column_array array_name | -column_set set_name ]
Performs the SQL query - sql. + sql. If a row is returned, sets variables to column values and returns 1. If no rows are returned, returns 0. If more than one row is returned, throws an error. -
- db_nextval
+- db_nextval
db_nextval sequence-name
Returns the next value for the sequence sequence-name (using a - SQL statement like SELECT - sequence-name.nextval FROM + SQL statement like SELECT + sequence-name.nextval FROM DUAL). If sequence pooling is enabled for the sequence, transparently uses a value from the pool if available to save a round-trip to the database (see Sequence Pooling).
- - + db_register_pooled_sequence @@ -563,48 +563,48 @@ size of pool-size sequence values (see Sequence Pooling). -
- db_string
+- db_string
db_string statement-name sql [ -default default ] [ -bind bind_set_id | -bind bind_value_list ]Returns the first column of the result of SQL query - sql. - If sql doesn't return a + sql. + If sql doesn't return a row, returns - default + default (or throws an error if - default is unspecified). Analogous to - database_to_tcl_string and - database_to_tcl_string_or_null. + default is unspecified). Analogous to + database_to_tcl_string and + database_to_tcl_string_or_null. -
- db_list
+- db_list
db_list statement-name sql [ -bind bind_set_id | -bind bind_value_list ]Returns a Tcl list of the values in the first column of the result of SQL query - sql. - If sql doesn't + sql. + If sql doesn't return any rows, returns an empty list. Analogous to - database_to_tcl_list. + database_to_tcl_list. -
- db_list_of_lists
+- db_list_of_lists
db_list_of_lists statement-name sql [ -bind bind_set_id | -bind bind_value_list ]Returns a Tcl list, each element of which is a list of all column values - in a row of the result of SQL query sql. If - sql doesn't return any rows, returns an empty list. - (Analogous to database_to_tcl_list_list.) + in a row of the result of SQL query sql. If + sql doesn't return any rows, returns an empty list. + (Analogous to database_to_tcl_list_list.) -
- db_dml
+- db_dml
db_dml statement-name sql \ [ -bind bind_set_id | -bind bind_value_list ] \ [ -blobs blob_list | -clobs clob_list | -blob_files blob_file_list | -clob_files clob_file_list ] -Performs the DML or DDL statement sql.
If a length-n list of blobs or clobs is provided, then the SQL +
Performs the DML or DDL statement sql.
If a length-n list of blobs or clobs is provided, then the SQL should return n blobs or clobs into the bind variables - :1, :2, ... :n. - blobs or clobs, if specified, + :1, :2, ... :n. + blobs or clobs, if specified, should be a list of individual BLOBs or CLOBs to insert; - blob_files or clob_files, if + blob_files or clob_files, if specified, should be a list of paths to files containing the data to - insert. Only one of -blobs, -clobs, - -blob_files, and -clob_files may be provided.
Example:
+ insert. Only one of -blobs, -clobs, + -blob_files, and -clob_files may be provided.Example:
db_dml insert_photos " insert photos(photo_id, image, thumbnail_image) @@ -613,37 +613,37 @@ " -blob_files [list "/var/tmp/the_photo" "/var/tmp/the_thumbnail"]- This inserts a new row into the photos table, with the contents - of the files /var/tmp/the_photo and - /var/tmp/the_thumbnail in the image and - thumbnail columns, respectively. + This inserts a new row into the photos table, with the contents + of the files /var/tmp/the_photo and + /var/tmp/the_thumbnail in the image and + thumbnail columns, respectively.
- - db_write_clob, - db_write_blob, - db_blob_get_file + db_write_clob, + db_write_blob, + db_blob_get_file
db_write_clob statement-name sql [ -bind bind_set_id | -bind bind_value_list ] db_write_blob statement-name sql [ -bind bind_set_id | -bind bind_value_list ] db_blob_get_file statement-name sql [ -bind bind_set_id | -bind bind_value_list ] -Analagous to ns_ora write_clob/write_blob/blob_get_file. +
Analagous to ns_ora write_clob/write_blob/blob_get_file. -
- db_release_unused_handles
+- db_release_unused_handles
db_release_unused_handles -Releases any allocated, unused database handles.
- db_transaction
+Releases any allocated, unused database handles.
- db_transaction
db_transaction code_block [ on_error { code_block } ] -Executes code_block transactionally. Nested - transactions are supported (end transaction is transparently - ns_db dml'ed when the outermost transaction completes). The - db_abort_transaction command can be used to abort all levels of - transactions. It is possible to specify an optional on_error +
Executes code_block transactionally. Nested + transactions are supported (end transaction is transparently + ns_db dml'ed when the outermost transaction completes). The + db_abort_transaction command can be used to abort all levels of + transactions. It is possible to specify an optional on_error code block that will be executed if some code in code_block throws - an exception. The variable errmsg will be bound in that scope. - If there is no on_error code, any errors will be propagated.
Example:
+ an exception. The variable errmsg will be bound in that scope. + If there is no on_error code, any errors will be propagated.Example:
proc replace_the_foo { col } { db_transaction { @@ -672,18 +672,18 @@ print_the_foo ; # Writes out "foo is 8" -- db_resultrows
+- db_resultrows
db_resultrowsReturns the number of rows affected or returned by the previous statement. -
- db_with_handle
+- db_with_handle
db_with_handle var code_block -Places a database handle into the variable var and - executes code_block. This is useful when you don't - want to have to use the new API (db_foreach, - db_1row, etc.), but need to use database handles explicitly.
Example:
+Places a database handle into the variable var and + executes code_block. This is useful when you don't + want to have to use the new API (db_foreach, + db_1row, etc.), but need to use database handles explicitly.
Example:
proc lookup_the_foo { foo } { db_with_handle db { @@ -703,15 +703,15 @@- - + db_nullify_empty_string
db_nullify_empty_string string
For true SQL purists, we provide the convenience function - db_nullify_empty_string, which returns - [db_null] if its string argument is the empty string + db_nullify_empty_string, which returns + [db_null] if its string argument is the empty string and can be used to encapsulate another Oracle quirk:
set baz "" @@ -729,8 +729,8 @@ # quirk)- To balance out this asymmetry, you can explicitly set baz to - null by writing: + To balance out this asymmetry, you can explicitly set baz to + null by writing:
db_dml foo_insert "insert into foo(baz) values(:1)" {[db_nullify_empty_string $baz]} Index: openacs-4/packages/acs-core-docs/www/dev-guide.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/dev-guide.html,v diff -u -r1.7.2.7 -r1.7.2.8 --- openacs-4/packages/acs-core-docs/www/dev-guide.html 29 Apr 2003 05:58:33 -0000 1.7.2.7 +++ openacs-4/packages/acs-core-docs/www/dev-guide.html 7 May 2003 17:40:58 -0000 1.7.2.8 @@ -1,2 +1,2 @@ -Chapter�9.�Development Reference Table of Contents
- OpenACS 4.6.3 Packages
- OpenACS 4.6.3 Data Models and the Object System
- The Request Processor
- The OpenACS Database Access API
- Using Templates in OpenACS 4.6.3
- Groups, Context, Permissions
- Writing OpenACS 4.6.3 Application Pages
- Parties in OpenACS 4.6.3
- OpenACS 4.x Permissions Tediously Explained
- Object Identity
- Programming with AOLserver
View comments on this page at openacs.org +Chapter�9.�Development Reference Table of Contents
- OpenACS 4.6.3 Packages
- OpenACS 4.6.3 Data Models and the Object System
- The Request Processor
- The OpenACS Database Access API
- Using Templates in OpenACS 4.6.3
- Groups, Context, Permissions
- Writing OpenACS 4.6.3 Application Pages
- Parties in OpenACS 4.6.3
- OpenACS 4.x Permissions Tediously Explained
- Object Identity
- Programming with AOLserver
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/docbook-primer.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/docbook-primer.html,v diff -u -r1.8.2.9 -r1.8.2.10 --- openacs-4/packages/acs-core-docs/www/docbook-primer.html 4 May 2003 06:30:02 -0000 1.8.2.9 +++ openacs-4/packages/acs-core-docs/www/docbook-primer.html 7 May 2003 17:40:58 -0000 1.8.2.10 @@ -1,21 +1,21 @@ -DocBook and Documentation +
DocBook and Documentation By claus@arsdigita.com, with additions by Roberto Mello and the OpenACS Community -
+
ArsDigita created a good documentation ground for us to build upon. Some sections of the documentation, however, lack details and examples; others are simply nonexistant. Our goal is to give OpenACS a superb documentation, so that users, developers and administrators of OpenACS installations can enjoy the system.
- OpenACS™ is a powerful system, with + OpenACS™ is a powerful system, with incredible possibilities and applications, but with this power comes some complexity and a learning curve that will only be atenuated by good documentation. This is what we are after.
- The documentation for OpenACS™ is + The documentation for OpenACS™ is written using DocBook XML. The reasons why we are using DocBook are explained in more details in the Why DocBook? section. I will add the reasons why @@ -28,11 +28,11 @@ SGML, with a couple extra rules. More details in the LDP Author Guide. -
In order to separate content and presentation, all OpenACS documentation will be marked up to conform to the DocBook XML DTD - + This enables us to publish in a variety of formats and relieves each contributor of the burden of presentation, freeing him to focus on content and sharing knowledge. @@ -53,15 +53,15 @@ list of elements and use more exotic features in your documents. The list is made up of SGML-elements but basically the same elements are valid in the XML DTD as long as you remember to: - +
Always close your tags with corresponding end-tags and to not use other tag minimization
Write all elements and attributes in lowercase
Quote all attributes -
You are going to need the following to work with the OpenACS Docbook XML documentation:
- Docbook XML @@ -72,7 +72,7 @@ Stylesheets (docbook-xsl) - The stylesheets to convert to HTML. We have been using a stylesheet based upon NWalsh's chunk.xsl. -
- xsltproc - The processor that +
- xsltproc - The processor that will take an XML document and, given a xsl stylesheet, convert it to HTML. It needs libxml2 and libxslt (available in RPM and DEB formats or from xmlsoft.org. @@ -81,7 +81,7 @@ mode. We have a intro to the PSGML Mode in Emacs as part of our documentation. You can read about other editing tools in the LDP Author Guide. -
After you have the tools mentioned above, you need to define a title for your document. Then start thinking about the possible sections and subsections you will have in your document. Make @@ -95,11 +95,11 @@ for acs-core-docs, especially the Detailed Design Documentation Template and the System/Application Requirements Template. -
The documentation for each package will make up a little "book" that is structured like this - examples are emphasized: - +
book : Docs for one package - templating @@ -117,31 +117,31 @@ ... : ...The actual content is split up into documents that start at a - sect1-level. These are then tied together in a top-level document that + sect1-level. These are then tied together in a top-level document that contains all the information above the line. This will be explained in more detail in a later document, and we will provide a set of templates for documenting an entire package.
For now you can take a look at the sources of these DocBook documents to get an idea of how they are tied together. -
- - Given that your job starts at the sect1-level, all your documents should open with a - <sect1>-tag and end - with the corresponding </sect1>. +
+ + Given that your job starts at the sect1-level, all your documents should open with a + <sect1>-tag and end + with the corresponding </sect1>.
- - You need to feed every <sect1> two attributes. The first attribute, - id, is standard and can be used with all elements. It comes in very - handy when interlinking between documents (more about this when talking about links in the section called “Links”). - The value of id has to be unique - throughout the book you're making since the id's in your - sect1's will turn into filenames when the book is parsed into HTML. + + You need to feed every <sect1> two attributes. The first attribute, + id, is standard and can be used with all elements. It comes in very + handy when interlinking between documents (more about this when talking about links in Section�, “Links”). + The value of id has to be unique + throughout the book you're making since the id's in your + sect1's will turn into filenames when the book is parsed into HTML.
- - The other attribute is xreflabel. The value of this is the text that will appear - as the link when referring to this sect1. + + The other attribute is xreflabel. The value of this is the text that will appear + as the link when referring to this sect1.
Right after the opening tag you put the title of the document - this is usually the same as - xreflabel-attribute. E.g. the top level of the document you're + xreflabel-attribute. E.g. the top level of the document you're reading right now looks like this:
<sect1 id="docbook-primer" xreflabel="aD DocBook Primer"> @@ -151,31 +151,31 @@ </sect1>- + Inside this container your document will be split up into - <sect2>'s, - each with the same requirements - id and xreflabel - attributes, and a <title>-tag inside. Actually, the xreflabel is never required in sections, but it makes linking to that section a lot easier. + <sect2>'s, + each with the same requirements - id and xreflabel + attributes, and a <title>-tag inside. Actually, the xreflabel is never required in sections, but it makes linking to that section a lot easier.
When it comes to naming your - sect2's and below, prefix them with some abbreviation of the id in the sect1 such as requirements-overview. -
- + sect2's and below, prefix them with some abbreviation of the id in the sect1 such as requirements-overview. +
+ For displaying a snippet of code, a filename or anything else you just want to appear as a part of a sentence, we will use the tag - <computeroutput>. - This takes the place of the HTML-tag <code> + <computeroutput>. + This takes the place of the HTML-tag <code>
For bigger chunks of code such as SQL-blocks, the tag - <programlisting> is used. Just wrap your code block in it; mono-spacing, indents and all that stuff is taken care of + <programlisting> is used. Just wrap your code block in it; mono-spacing, indents and all that stuff is taken care of automatically. -
+ Linking falls into two different categories: inside the book you're making and outside:
- 1. Inside linking, cross-referencing other parts of your book
- By having unique id's you can cross-reference any part of your book + By having unique id's you can cross-reference any part of your book with a simple tag, regardless of where that part is. -
Check out how I link to a subsection of the Developer's Guide:
+Check out how I link to a subsection of the Developer's Guide:
Put this in your XML: @@ -191,10 +191,10 @@Note that even though this is an empty tag, you have to either:
- Provide the end-tag, </xref>, or + Provide the end-tag, </xref>, or
- Put a slash before the ending-bracket: <xref linkend="blahblah"/> -
If the section you link to hasn't a specified xreflabel-attribute, + Put a slash before the ending-bracket: <xref linkend="blahblah"/> +
If the section you link to hasn't a specified xreflabel-attribute, the link is going to look like this:
Put this in your XML: @@ -206,26 +206,26 @@ And the output is: - Find information about what a package looks like in - the section called “What a Package Looks Like” + Section�, “What a Package Looks Like”- Note that since I haven't provided an xreflabel for the subsection, - packages-looks, the + Note that since I haven't provided an xreflabel for the subsection, + packages-looks, the parser will try its best to explain where the link takes you.
- 2. Linking outside the documentation
- + If you're hyper-linking out of the documentation, it works almost the same way as HTML - the tag is just a little different - (<ulink>): + (<ulink>):
<ulink url="http://www.oracle.com/">Oracle Corporation</ulink>....will create a hyper-link to Oracle in the HTML-version of the documentation.
NOTE: Do NOT use ampersands in your hyper links. These are reserved for referencing - entities, which is exactly how you'll make an ampersand: & + entities, which is exactly how you'll make an ampersand: & -
NOTE: Currently this section currently only takes HTML-output into consideration - not a printed version
@@ -234,15 +234,15 @@ do it, so if you want to start converting your documents right away, start out with the ones without graphics ;)
- + To insert a graphic we use the elements - <mediaobject>, - <imageobject>, + <mediaobject>, + <imageobject>, and - <imagedata>. + <imagedata>. The news is that you have to provide two versions of all your graphics - one for the Web (probably a GIF or a JPEG) and one for print (EPS). Finally you should provide a brief description wrapped in - <textobject> - + <textobject> - in HTML this will be the ALT text.
<mediaobject> @@ -259,15 +259,15 @@Put your graphics in a separate directory ("images") and link to them only with relative paths. -
+ Here's how you make the DocBook equivalent of the three usual HTML-lists:
- 1. How to make an <ul>
- Making an unordered list is pretty much like doing the same thing in HTML - if you close your <li>, that is. The only differences are that each list item has to be wrapped in something more, such as - <para>, and that the tags are called - <itemizedlist> + Making an unordered list is pretty much like doing the same thing in HTML - if you close your <li>, that is. The only differences are that each list item has to be wrapped in something more, such as + <para>, and that the tags are called + <itemizedlist> and - <listitem>: + <listitem>:
<itemizedlist> @@ -277,20 +277,20 @@ </itemizedlist>- 2. How to make an <ol>
The ordered list is like the preceding, except that you use - <orderedlist> instead:
+ <orderedlist> instead:<orderedlist> <listitem><para>Stuff goes here</para></listitem> <listitem><para>More stuff goes here</para></listitem> </orderedlist>- 3. How to make a <dl>
- This kind of list is called a variablelist and these are the tags you'll need to + This kind of list is called a variablelist and these are the tags you'll need to make it happen: - <variablelist>, - <varlistentry>, - <term> and - <listitem>:
+ <variablelist>, + <varlistentry>, + <term> and + <listitem>:<variablelist> <varlistentry> @@ -304,10 +304,10 @@ </varlistentry> </variablelist> -+ DocBook supports several types of tables, but in most cases, the - <informaltable> + <informaltable> is enough:
<informaltable frame="all"> @@ -339,26 +339,26 @@ With our current XSL-style-sheet, the output of the markup above will be a simple HTML-table:
a1 b1 c1 a2 b2 c2 a3 b3 c3 If you want cells to span more than one row or column, it gets a bit more complicated - check out - <table> + <table> for an example. -
+ Our documentation uses two flavors of emphasis - italics and bold type. DocBook uses one - - <emphasis>. + <emphasis>.
- The <emphasis> tag defaults to italics when parsed. If you're looking for - emphasizing with bold type, use <emphasis role="strong">. -
+ The <emphasis> tag defaults to italics when parsed. If you're looking for + emphasizing with bold type, use <emphasis role="strong">. +
Marking up index-words may not have any importance for the HTML-output, but in order to make it easier to make a nice print-version of the documentation, you should mark up words in your documents that you would like to see show up in an index one day.
Use - <indexterm>, - <primary> and - <secondary> + <indexterm>, + <primary> and + <secondary> for this. See these links for an explanation. -
Note
+Note
This section is quoted almost verbatim from the LDP Author Guide.Once you have the Docbook Tools @@ -386,7 +386,7 @@ following command:
bash$ xsltproc /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/chunk.xsl filename.xml -
- +
- The LDP Author Guide has a lot of good information, a table of docbook elements and their "look" in HTML and lots of good links @@ -416,7 +416,7 @@ Perl script that gets you most of the way. -
Document Revision # Action Taken, Notes When? By Whom? 0.4 +
Document Revision # Action Taken, Notes When? By Whom? 0.4 Fixed some typos. 8/3/2002 Vinod Kurup 0.3 Added OpenACS information, updated tools, added Index: openacs-4/packages/acs-core-docs/www/eng-standards-constraint-naming.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/eng-standards-constraint-naming.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/eng-standards-constraint-naming.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/eng-standards-constraint-naming.html 7 May 2003 17:40:58 -0000 1.8.2.9 @@ -1,8 +1,8 @@ - Constraint naming standard
+Constraint naming standard
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Constraint naming standard is important for one reason: The SYS_* name oracle assigns to unnamed constraints is not very understandable. By correctly naming all contraints, we can quickly associate a particular constraint @@ -11,14 +11,14 @@
Why do we need a naming convention?Oracle limits names, in general, to 30 characters, which is hardly enough for a human readable constraint name. -
We propose the following naming convention for all constraints, with the following abbreviations taken from Oracle Docs at http://oradoc.photo.net/ora81/DOC/server.815/a67779/ch4e.htm#8953. Note that we shortened all of the constraint abbrevations to two characters to save room. -
Constraint type Abbreviation references (foreign key) fk unique un primary key pk check ck not null nn +
Constraint type Abbreviation references (foreign key) fk unique un primary key pk check ck not null nn <table name>_<column_name>_<constraint abbreviation>
In reality, this won't be possible because of the character limitation on @@ -28,7 +28,7 @@
Truncate the column name until it fits.
If the constraint name is still too long, you should consider rewriting your entire data model :) -
Notes:
If you have to abbreviate the table name for one of the constraints, abbreviate it for all the constraints
If you are defining a multi column constraint, try to truncate the two column names evenly
+Notes:
If you have to abbreviate the table name for one of the constraints, abbreviate it for all the constraints
If you are defining a multi column constraint, try to truncate the two column names evenly
create table example_topics ( topic_id integer constraint example_topics_topic_id_pk @@ -52,7 +52,7 @@ constraint cne_example_id_one_line_unq unique(example_id, one_line_description) ); -Naming primary keys might not have any obvious advantages. However, here's an example where naming the primary key really helps (and this is by no means a rare case! @@ -73,7 +73,7 @@
Isn't it nice to see "EXAMPLE_TOPICS_TOPIC_ID_PK" in the trace and know exactly which table oracle is using at each step? -
ArsDigita is split on whether or not we should be naming not null constraints... So, if you want to name them, please do so and follow the above naming standard. But, naming not null constraints is not a requirement at ArsDigita.
About Naming the not null constraintsIndex: openacs-4/packages/acs-core-docs/www/eng-standards-filenaming.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/eng-standards-filenaming.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/eng-standards-filenaming.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/eng-standards-filenaming.html 7 May 2003 17:40:58 -0000 1.8.2.9 @@ -1,82 +1,82 @@ -
ACS File Naming and Formatting Standards By michael@arsdigita.com and +
ACS File Naming and Formatting Standards By michael@arsdigita.com and aure@arsdigita.com
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.To ensure consistency (and its collateral benefit, maintainability), we define and adhere to standards in the following areas: -
+
Usually we organize our files so that they mainly serve one of the following three purposes:
displaying objects and their properties
manipulating or acting on objects in some way (by creating, editing, linking, etc)
housing procedures, packages, data models and other prerequisite code Essentially, we want our files named in a fashion that reflects their purpose.
Under the page root (and the template root if using the Style package):
For naming files that enable a specific action on an object, use this format:
-object-verb.extension +object-verb.extension
For example, the page to erase a user's portrait from the database is -/admin/users/portrait-erase.tcl. +/admin/users/portrait-erase.tcl.
However, modules typically deal with only one primary type of object - e.g., the Bookmarks module deals mainly with bookmarks - and so action-type files in modules don't need to be specified by the object they act on. Example: the user pages -for the Bookmarks module live in the /bookmarks/ -directory, and so there is no need to name the bookmark editing page with a redundant url: /bookmarks/bookmark-edit.tcl. Instead, we omit the object type, and use this convention: +for the Bookmarks module live in the /bookmarks/ +directory, and so there is no need to name the bookmark editing page with a redundant url: /bookmarks/bookmark-edit.tcl. Instead, we omit the object type, and use this convention:
-verb.extension +verb.extension
-Thus, the page to edit a bookmark is /bookmarks/edit.tcl. +Thus, the page to edit a bookmark is /bookmarks/edit.tcl.
For naming files that display the properties of a primary object - such as the bookmark object within the bookmark module - use this convention:
-one.extension +one.extension
For example, the page to view one bookmark is -/bookmarks/one.tcl. Note that no verb is necessary for display-type files. +/bookmarks/one.tcl. Note that no verb is necessary for display-type files.
Otherwise, if the object to be displayed is not the primary feature of a module, simply omit the verb and use the object name:
-object.extension +object.extension
For example, the page to view the properties of an ecommerce product is -/ecommerce/product.tcl. -
For naming files in a page flow, use the convention:
foobar.extension (Step 1)
foobar-2.extension (Step 2)
...
foobar-N.extension (Step N)
-where foobar is determined by the above +/ecommerce/product.tcl. +
For naming files in a page flow, use the convention:
foobar.extension (Step 1)
foobar-2.extension (Step 2)
...
foobar-N.extension (Step N)
+where foobar is determined by the above rules.
Typically, we use a three-step page flow when taking user information: -
Present a form to the user
Present a confirmation page to the user
Perform the database transaction, then redirect
Put data model files in /www/doc/sql, and name them +
Present a form to the user
Present a confirmation page to the user
Perform the database transaction, then redirect
Put data model files in /www/doc/sql, and name them for the modules towards which they are used:
-module.sql +module.sql
In the Tcl library directory:
For files that contain module-specific procedures, use the convention:
-module-procs.tcl +module-procs.tcl
For files that contain procedures that are part of the core ACS, use the convention:
-ad-description-procs.tcl -
File names also appear within pages, as linked URLs and form targets. When they do, always use abstract -URLs (e.g., user-delete instead of -user-delete.tcl), because they enhance maintainability. +URLs (e.g., user-delete instead of +user-delete.tcl), because they enhance maintainability.
Similarly, when linking to the index page of a directory, do not -explicitly name the index file (index.tcl, -index.adp, index.html, etc.). Instead, use +explicitly name the index file (index.tcl, +index.adp, index.html, etc.). Instead, use just the directory name, for both relative links -(subdir/) and absolute links -(/top-level-dir/). If linking to the directory in which -the page is located, use the empty string (""), which +(subdir/) and absolute links +(/top-level-dir/). If linking to the directory in which +the page is located, use the empty string (""), which browsers will resolve correctly. -
Include the appropriate standard header in all scripts. The first line should be a comment specifying the file path relative to the ACS root directory. e.g. -
+
# /www/index.tcl
or -
+
# /tcl/module-defs.tcl
For static content files (html or adp), include a CVS identification tag as a @@ -96,7 +96,7 @@ This can be at the top or bottom of the file.
Using ad_page_contractFor non-library Tcl files (those not in the private Tcl directory), -use ad_page_contract +use ad_page_contract after the file path comment (this supersedes set_the_usual_form_variables and ad_return_complaint). Here is an example of using ad_page_contract, which serves both documentation and page input @@ -120,32 +120,32 @@ {persistent_cookie_p f} }
-Salient features of ad_page_contract: +Salient features of ad_page_contract:
A mandatory documentation string is the first argument. This has the standard form with javadoc-style @author, @cvs-id, etc, and should contain a short description of the recieved variables and any necessary explanations.
The second argument specifies the page inputs. The syntax for switches/flags (e.g. multiple-list, array, etc.) uses a colon (:) followed by any number of flags separated by commas (,), -e.g. foo:integer,multiple,trim. In particular, multiple and -array are the flags that correspond to the old -ad_page_variables flags.
There are new flags: trim, notnull and -optional. They do what you'd expect; values will not be +e.g. foo:integer,multiple,trim. In particular, multiple and +array are the flags that correspond to the old +ad_page_variables flags.
There are new flags: trim, notnull and +optional. They do what you'd expect; values will not be trimmed, unless you mark them for it; empty strings are valid input, unless you specify notnull; and a specified variable will be considered required, -unless you declare it optional.
ad_page_contract can do validation for you: the flags integer -and sql_identifier will make sure that the values -supplied are integers/sql_identifiers. The integer flag +unless you declare it optional.
ad_page_contract can do validation for you: the flags integer +and sql_identifier will make sure that the values +supplied are integers/sql_identifiers. The integer flag will also trim leading zeros. Note that unless you specify -notnull, both will accept the empty string. -
Note that ad_page_contract does not generate +notnull, both will accept the empty string. +
Note that ad_page_contract does not generate QQvariables, which were automatically created by ad_page_variables and set_the_usual_form_variables. The use of bind variables makes such previous variable syntax obsolete.
Using ad_library-For shared Tcl library files, use ad_library after +For shared Tcl library files, use ad_library after the file path comment. Its only argument is a doc_string in the standard (javadoc-style) format, like -ad_page_contract. Don't forget to put the @cvs-id in +ad_page_contract. Don't forget to put the @cvs-id in there. Here is an example of using ad_library:
# tcl/wp-defs.tcl @@ -168,12 +168,12 @@ -- -- $Id$-Of course, replace "--" with the comment delimiter +Of course, replace "--" with the comment delimiter appropriate for the language in which you are programming. -
Construct the page as one Tcl variable (name it -page_content), and then send it back to the browser with -one call to doc_return, which will call +page_content), and then send it back to the browser with +one call to doc_return, which will call db_release_unused_handles prior to executing ns_return, effectively combining the two operations.
@@ -201,21 +201,21 @@ doc_return 200 text/html $page_content
-The old convention was to call ReturnHeaders and -then ns_write for each distinct chunk of the page. This +The old convention was to call ReturnHeaders and +then ns_write for each distinct chunk of the page. This approach has the disadvantage of tying up a scarce and valuable resource (namely, a database handle) for an unpredictable amount of time while sending packets back to the browser, and so it should be avoided in most cases. (On the other hand, for a page that requires an expensive database query, it's better to call -ad_return_top_of_page +ad_return_top_of_page first, so that the user is not left to stare at an empty page while the query is running.)
Local procedures (i.e., procedures defined and used only within one -page) should be prefixed with "module_" and +page) should be prefixed with "module_" and should be used rarely, only when they are exceedingly useful.
All files that prepare HTML to display should end with [ad_footer] or @@ -226,7 +226,7 @@ edit ad_header (which quite possibly can start a <table>) and ad_footer (which may need to end the table started in ad_footer) to customize the look and feel of the entire site. -
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/eng-standards-plsql.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/eng-standards-plsql.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/eng-standards-plsql.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/eng-standards-plsql.html 7 May 2003 17:40:58 -0000 1.8.2.9 @@ -1,5 +1,5 @@ -PL/SQL Standards +
PL/SQL Standards By richardl@arsdigita.com and yon@arsdigita.com
@@ -12,7 +12,7 @@ our product will be useful long after the current people building and maintaining it are around. Following are some standards and guidelines that will help us achieve this goal: -
+
All PL/SQL code must be well documented. We must write code that is maintainable by others, this is especially true in our case because we are building an open source toolkit than anyone can @@ -24,7 +24,7 @@ as is possible given the nature of team development. This means carrying style and other conventions suchs as naming within an application, not just within one file. -
Encapsulation of related fuctionality is key to maintainability and upgradeability of our software. Try to bundle your code into packages @@ -55,13 +55,13 @@ show errors
- Always use create or replace procedure|function + Always use create or replace procedure|function <proc_or_func_name>. It makes reloading packages much easier and painless to someone who is upgrading or fixing a bug.
- Always qualify end statements, i.e., the - end statement for a package should be end - <package_name>;, not just end;; same + Always qualify end statements, i.e., the + end statement for a package should be end + <package_name>;, not just end;; same goes for procedures, functions, package bodies, and triggers.
Always use the "show errors" SQL*Plus command after each PL/SQL @@ -73,11 +73,11 @@ the v_* and *_in syntax in favor of named parameters notation:
- + acs_user.create(first_names => 'Jane', last_name => 'Doe', etc.) instead of - + acs_user.create(first_names_in => 'Jane', last_name_in => 'Doe', etc.) @@ -120,11 +120,11 @@ Use 't' and 'f' for booleans, not the PL/SQL "boolean" datatype because it can't be used in SQL queries.- All new functions (e.g., acs_object.new, + All new functions (e.g., acs_object.new, party.new, etc.) should optionally accept an ID:
- + create or replace package acs_object as function new ( @@ -138,12 +138,12 @@- takes the optional argument object_id. Do this to + takes the optional argument object_id. Do this to allow people to use the same API call when they are doing double click protection, that is, tehy have already gotten an - object_id and now they want to create the object with - that object_id. -
Some general style guidelines to follow for the purpose of consistency across applications.
Index: openacs-4/packages/acs-core-docs/www/eng-standards-versioning.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/eng-standards-versioning.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/eng-standards-versioning.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/eng-standards-versioning.html 7 May 2003 17:40:58 -0000 1.8.2.9 @@ -1,5 +1,5 @@ -
Release Version Numbering
+Release Version Numbering
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.@@ -36,7 +36,7 @@ particular release. To translate between a distribution tar file (acs-3.2.2.tar.gz) and a CVS tag, just swap '.' for '-' and add the release date. The entire release history of the toolkit is recorded -in the tags for the top-level readme.txt file: +in the tags for the top-level readme.txt file:
> cvs log readme.txt RCS file: /usr/local/cvsroot/acs/readme.txt,v @@ -72,7 +72,7 @@In the future, OpenACS packages should follow this same convention on version numbers. -
So what distinguishes an alpha release from a beta +
So what distinguishes an alpha release from a beta release? Or from a production release? We follow a specific set of rules for how OpenACS makes the transition from one state of maturity to the next.
Every release must pass the minimum requirements that it cleanly Index: openacs-4/packages/acs-core-docs/www/eng-standards.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/eng-standards.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/eng-standards.html 29 Apr 2003 05:58:33 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/eng-standards.html 7 May 2003 17:40:58 -0000 1.6.2.8 @@ -1,2 +1,2 @@ -
Chapter�10.�Engineering Standards View comments on this page at openacs.org +Chapter�10.�Engineering Standards View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/filename.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/filename.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/filename.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/filename.html 7 May 2003 17:40:58 -0000 1.8.2.9 @@ -1,5 +1,5 @@ -Detailed Design Documentation Template By You
+
Detailed Design Documentation Template By You
NOTE: Some of the sections of this template may not apply to your package, e.g. there may be no user-visible UI elements for a component of the OpenACS Core. Furthermore, it may be easier in some circumstances @@ -14,9 +14,9 @@ Also, bear in mind the audience for detailed design: fellow programmers who want to maintain/extend the software, AND parties interested in evaluating software quality. -
When applicable, each of the following items should receive its own link: -
User directory
OpenACS administrator directory
Subsite administrator directory
Tcl script directory (link to the API browser page for the package)
PL/SQL file (link to the API browser page for the package)
Data model
Requirements document
ER diagram
Transaction flow diagram
+
User directory
OpenACS administrator directory
Subsite administrator directory
Tcl script directory (link to the API browser page for the package)
PL/SQL file (link to the API browser page for the package)
Data model
Requirements document
ER diagram
Transaction flow diagram
This section should provide an overview of the package and address at least the following issues:
What this package is intended to allow the user (or different @@ -33,15 +33,15 @@ Note: it's entirely possible that a discussion of what a package is not intended to do differs from a discussion of future improvements for the package. -
For a given set of requirements, typically many possible implementations and solutions exist. Although eventually only one solution is implemented, a discussion of the alternative solutions canvassed - noting why they were rejected - proves helpful to both current and future developers. All readers would be reminded as to why and how the particular solution developed over time, avoiding re-analysis of problems already solved. -
Although currently only a few package documentation pages contain a discussion of competing software, (e.g. chat, portals), this section should be present whenever such competition exists. @@ -52,7 +52,7 @@ lacks.
Note that such a discussion may differ from a discussion of a package's potential future improvements. -
No single design solution can optimize every desirable software attribute. For example, an increase in the security of a system will likely entail a decrease in its ease-of-use, and an increase in the @@ -62,7 +62,7 @@ should include a discussion of the tradeoffs involved with the design chosen, and the reasons for your choices. Some areas of importance to keep in mind are: -
Areas of interest to users:
Performance: availability and efficiency
Flexibility
Interoperability
Reliability and robustness
Usability
Areas of interest to developers:
Maintainability
Portability
Reusability
Testability
+
Areas of interest to users:
Performance: availability and efficiency
Flexibility
Interoperability
Reliability and robustness
Usability
Areas of interest to developers:
Maintainability
Portability
Reusability
Testability
Here's where you discuss the abstractions used by your package, such as the procedures encapsulating the legal transactions on the data model. Explain the organization of procedures and their @@ -80,7 +80,7 @@ handle transactions, instead of encapsulating them via procedures). Experience has taught us that we need to focus on the API for maintainability of our systems in the face of constant change. -
The data model discussion should do more than merely display the SQL code, since this information is already be available via a link in the "essentials" section above. Instead, there should be a high-level @@ -97,7 +97,7 @@ packages.
Transactions
Discuss modifications which the database may undergo from your package. Consider grouping legal transactions according to the invoking user class, i.e. transactions by an OpenACS-admin, by - subsite-admin, by a user, by a developer, etc.
In this section, discuss user interface issues and pages to be built; you can organize by the expected classes of users. These may include:
Developers
OpenACS administrators (previously known as site-wide administrators)
Subsite administrators
End users
@@ -114,26 +114,26 @@ Finally, note that as our templating system becomes more entrenched within the OpenACS, this section's details are likely to shift from UI specifics to template interface specifics. -
Under OpenACS 4.6.3, parameters are set at two levels: at the global level by the OpenACS-admin, and at the subsite level by a sub-admin. In this section, list and discuss both levels of parameters. -
If the system presently lacks useful/desirable features, note details here. You could also comment on non-functional improvements to the package, such as usability.
Note that a careful treatment of the earlier "competitive analysis" section can greatly facilitate the documenting of this section. -
Although a system's data model file often contains this information, this isn't always the case. Furthermore, data model files often undergo substantial revision, making it difficult to track down the system creator. An additional complication: package documentation may be authored by people not directly involved in coding. Thus to avoid unnecessary confusion, include email links to the following roles as they may apply: -
System creator
System owner
Documentation author
The revision history table below is for this template - modify it as needed for your actual design document.
Document Revision # Action Taken, Notes When? By Whom? 0.3 Edited further, incorporated feedback from Michael Yoon 9/05/2000 Kai Wu 0.2 Edited 8/22/2000 Kai Wu 0.1 Creation 8/21/2000 Josh Finkler, Audrey McLoghlin ($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/for-everyone.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/for-everyone.html,v diff -u -r1.7.2.6 -r1.7.2.7 --- openacs-4/packages/acs-core-docs/www/for-everyone.html 29 Apr 2003 05:58:33 -0000 1.7.2.6 +++ openacs-4/packages/acs-core-docs/www/for-everyone.html 7 May 2003 17:40:58 -0000 1.7.2.7 @@ -1,2 +1,2 @@ -Part�I.�OpenACS For Everyone High level information: What is OpenACS?
Table of Contents
Prev Home Next OpenACS Documentation Up Chapter�1.�High level information: What is OpenACS?
docs@openacs.orgView comments on this page at openacs.org +Part�I.�OpenACS For Everyone High level information: What is OpenACS?
Table of Contents
Prev Home Next OpenACS Documentation Up Chapter�1.�High level information: What is OpenACS?
docs@openacs.orgView comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/general-documents.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/general-documents.html,v diff -u -r1.7.2.6 -r1.7.2.7 --- openacs-4/packages/acs-core-docs/www/general-documents.html 29 Apr 2003 05:58:33 -0000 1.7.2.6 +++ openacs-4/packages/acs-core-docs/www/general-documents.html 7 May 2003 17:40:58 -0000 1.7.2.7 @@ -1,2 +1,2 @@ -Chapter�1.�High level information: What is OpenACS? Table of Contents
View comments on this page at openacs.org +Chapter�1.�High level information: What is OpenACS? Table of Contents
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/groups-design.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/groups-design.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/groups-design.html 29 Apr 2003 05:58:33 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/groups-design.html 7 May 2003 17:40:58 -0000 1.6.2.8 @@ -1,32 +1,32 @@ -OpenACS 4 Groups Design +
OpenACS 4 Groups Design by Rafael H. Schloming and Mark Thomas
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -
User directory
Sitewide administrator directory
Subsite administrator directory
TCL script directory
Data model
PL/SQL file
ER diagram
Transaction flow diagram
User directory
Sitewide administrator directory
Subsite administrator directory
TCL script directory
Data model
PL/SQL file
ER diagram
Transaction flow diagram
Almost all database-backed websites have users, and need to model the grouping of users. The OpenACS 4 Parties and Groups system is intended to provide the flexibility needed to model complex real-world organizational structures, particularly to support powerful subsite services; that is, where one OpenACS installation can support what appears to the user as distinct web services -for different user communities.
The primary limitation of the OpenACS 3.x user group system is that it +for different user communities.
The primary limitation of the OpenACS 3.x user group system is that it restricts the application developer to representing a "flat group" -that contains only users: The user_groups table may contain the -group_id of a parent group, but parent-child relationship +that contains only users: The user_groups table may contain the +group_id of a parent group, but parent-child relationship support is limited because it only allows one kind of relationship between groups to be represented. Moreover, the Oracle database's limited support for tree-like structures makes the queries over these relationships expensive.
In addition, the Module Scoping design in OpenACS 3.0 introduced a party abstraction - a thing that is a person or a group of people - though not in the form of an explicit table. Rather, the triple of -scope, user_id, and group_id columns +scope, user_id, and group_id columns was used to identify the party. One disadvantage of this design convention is that it increases a data model's complexity by requiring the programmer to:
add these three columns to each "scoped" table
define a multi-column check constraint to protect against data corruption -(e.g., a row with a scope value of "group" but a null -group_id)
perform extra checks in Tcl and PL/SQL -functions and procedures to check both the user_id and -group_id values
The core of the Group Systems data model is quite simple, but it was designed in the hopes of modeling "real world" organizations which can be complex graph structures. The Groups System only considers groups that can be modeled using directed acyclic graphs, but queries over these @@ -39,44 +39,44 @@ without making the system too complex or too slow. The added triggers, views, and tables and will increase storage requirements and the insert and delete times in an effort to speed access time. The limited flexibility (no updates -on membership) trades against the complexity of the code.
The Group System data model consists of the following tables:
- parties +on membership) trades against the complexity of the code.
The Group System data model consists of the following tables:
- parties
The set of all defined parties: any person, user, or -group must have a corresponding row in this table.
- persons +group must have a corresponding row in this table.
- persons
The set of all defined persons. To allow easy sorting of persons, the name requirement 30.10 is met by -splitting the person's name into two columns: first_names and -last_name.
- users +splitting the person's name into two columns: first_names and +last_name.
- users
The set of all registered users; this table includes information about -the user's email address and the user's visits to the site.
- user_preferences +the user's email address and the user's visits to the site.
- user_preferences -
Preferences for the user.
- groups +
Preferences for the user.
- groups -
The set of all defined groups.
- group_types +
The set of all defined groups.
- group_types
When a new type of group is created, this table holds additional -knowledge level attributes for the group and its subtypes.
- membership_rels +knowledge level attributes for the group and its subtypes.
- membership_rels
The set of direct membership relationships between a group and a -party.
- group_member_index +party.
- group_member_index
A mapping of a party P to the groups {Gi}the party is a member of; this mapping -includes the type of relationship by including the appropriaterel_id -from the membership_rels table.
- composition_rels +includes the type of relationship by including the appropriaterel_id +from the membership_rels table.
- composition_rels
The set of direct component relationships between a group and another -group.
- group_component_index +group.
- group_component_index
A mapping of a group Gto the set of groups {Gi} that G is a component of; this mapping includes the type of relationship by including the -appropriaterel_id from the composition_rels table.
New groups are created through the group.new constructor. +appropriaterel_id from the composition_rels table.
New groups are created through the group.new constructor. When a specialized type of group is required, the group type can be extended by an application developer. Membership constraints can be specified at -creation time by passing a parent group to the constructor.
The membership_rels and composition_rels tables indicate +creation time by passing a parent group to the constructor.
The membership_rels and composition_rels tables indicate a group's direct members and direct components; these tables do not provide a record of the members or components that are in the group by virtue of being a member or component of one of the group's component groups. @@ -86,60 +86,60 @@ queries responsive, the data model includes triggers (described in the next paragraph) which watch for changes in membership or composition and update tables that maintain the group party mappings, i.e., -group_member_index and group_component_index. One can think -of these tables as a manually maintained index.
The following triggers keep the group_*_index tables up to -date:
- membership_rels_in_tr +group_member_index and group_component_index. One can think +of these tables as a manually maintained index.
The following triggers keep the group_*_index tables up to +date:
- membership_rels_in_tr
Is executed when a new group/member relationship is created (an insert on -membership_rels)
- membership_rels_del_tr +membership_rels)
- membership_rels_del_tr
Is executed when a group/member relationship is deleted (a delete on -membership_rels)
- composition_rels_in_tr +membership_rels)
- composition_rels_in_tr
Is executed when a new group/component relationship is created (an insert -on composition_rels)
- composition_rels_del_tr +on composition_rels)
- composition_rels_del_tr
Is executed when a group/component relationship is deleted (a delete on -composition_rels)
The data model provides the following views onto the -group_member_index and group_component_index tables. No -code outside of Groups System should modify the group_*_index -tables.
- group_member_map +composition_rels)
The data model provides the following views onto the +group_member_index and group_component_index tables. No +code outside of Groups System should modify the group_*_index +tables.
- group_member_map
A mapping of a party to the groups the party is a member of; this mapping -includes the type of relationship by including the appropriaterel_id -from the membership_rels table.
- group_approved_member_map +includes the type of relationship by including the appropriaterel_id +from the membership_rels table.
- group_approved_member_map
A mapping of a party to the groups the party is an approved member of -(member_state is 'approved'); this mapping includes the type -of relationship by including the appropriaterel_id from the -membership_rels table.
- group_distinct_member_map +(member_state is 'approved'); this mapping includes the type +of relationship by including the appropriaterel_id from the +membership_rels table.
- group_distinct_member_map
A person may appear in the group member map multiple times, for example, by being a member of two different groups that are both components of a third group. This view is strictly a mapping of approved members -to groups.
- group_component_map +to groups.
- group_component_map
A mapping of a group Gto the set of groups {Gi} group G is a component of; this mapping includes the type of relationship by including the -appropriaterel_id from the composition_rels table.
- party_member_map +appropriaterel_id from the composition_rels table.
- party_member_map
A mapping of a party P to the set of parties {Pi} party P is a member -of.
- party_approved_member_map +of.
- party_approved_member_map
A mapping of a party P to the set of parties {Pi} party P is an -approved member of.
The API consists of tables and views and PL/SQL functions. -
The group_types table is used to create new types of groups.
The group_member_map, group_approved_member_map, -group_distinct_member_map, group_component_map, -party_member_map, and party_approved_member_map views are -used to query group membership and composition.
Person
person.new creates a new person and returns the -person_id. The function must be given the full name of the person in -two pieces: first_names and last_name. All other fields are -optional and default to null except for object_type which defaults -to person and creation_date which defaults to sysdate. The +
The group_types table is used to create new types of groups.
The group_member_map, group_approved_member_map, +group_distinct_member_map, group_component_map, +party_member_map, and party_approved_member_map views are +used to query group membership and composition.
Person
person.new creates a new person and returns the +person_id. The function must be given the full name of the person in +two pieces: first_names and last_name. All other fields are +optional and default to null except for object_type which defaults +to person and creation_date which defaults to sysdate. The interface for this function is:
function person.new ( person_id persons.person_id%TYPE, @@ -152,19 +152,19 @@ first_names persons.first_names%TYPE, last_name persons.last_name%TYPE ) return persons.person_id%TYPE; -person.delete deletes the person whose person_id is +
person.delete deletes the person whose person_id is passed to it. The interface for this procedure is:
procedure person.delete ( person_id persons.person_id%TYPE ); -person.name returns the name of the person whose -person_id is passed to it. The interface for this function is:
+person.name returns the name of the person whose +person_id is passed to it. The interface for this function is:
function person.name ( person_id persons.person_id%TYPE ) return varchar; -User
acs_user.new creates a new user and returns the user_id. +
User
acs_user.new creates a new user and returns the user_id. The function must be given the user's email address and the full name of -the user in two pieces: first_names and last_name. All +the user in two pieces: first_names and last_name. All other fields are optional. The interface for this function is:
function acs_user.new ( user_id users.user_id%TYPE, @@ -183,19 +183,19 @@ screen_name users.screen_name%TYPE, email_verified_p users.email_verified_p%TYPE ) return users.user_id%TYPE; -acs_user.delete deletes the user whose user_id is passed +
acs_user.delete deletes the user whose user_id is passed to it. The interface for this procedure is:
procedure acs_user.delete ( user_id users.user_id%TYPE ); -acs_user.receives_alerts_p returns 't' if the user should +
acs_user.receives_alerts_p returns 't' if the user should receive email alerts and 'f' otherwise. The interface for this function is:
function acs_user.receives_alerts_p ( user_id users.user_id%TYPE ) return varchar; -Use the procedures acs_user.approve_email and -acs_user.unapprove_email to specify whether the user's email +
Use the procedures acs_user.approve_email and +acs_user.unapprove_email to specify whether the user's email address is valid. The interface for these procedures are:
procedure acs_user.approve_email ( user_id users.user_id%TYPE @@ -204,11 +204,11 @@ procedure acs_user.unapprove_email ( user_id users.user_id%TYPE ); -Group
acs_group.new creates a new group and returns the -group_id. All fields are optional and default to null except for -object_type which defaults to 'group', -creation_date which defaults to sysdate, and -group_name which is required. The interface for +
Group
acs_group.new creates a new group and returns the +group_id. All fields are optional and default to null except for +object_type which defaults to 'group', +creation_date which defaults to sysdate, and +group_name which is required. The interface for this function is:
function acs_group.new ( group_id groups.group_id%TYPE, @@ -220,21 +220,21 @@ url parties.url%TYPE, group_name groups.group_name%TYPE ) return groups.group_id%TYPE; -acs_group.name returns the name of the group whose -group_id is passed to it. The interface for this function is:
+acs_group.name returns the name of the group whose +group_id is passed to it. The interface for this function is:
function acs_group.name ( group_id groups.group_id%TYPE ) return varchar; -acs_group.member_p returns 't' if the specified party is +
acs_group.member_p returns 't' if the specified party is a member of the specified group. Returns 'f' otherwise. The interface for this function is:
function acs_group.member_p ( group_id groups.group_id%TYPE, party_id parties.party_id%TYPE, ) return char; -Membership Relationship
membership_rel.new creates a new membership relationship type -between two parties and returns the relationship type's rel_id. -All fields are optional and default to null except for rel_type +
Membership Relationship
membership_rel.new creates a new membership relationship type +between two parties and returns the relationship type's rel_id. +All fields are optional and default to null except for rel_type which defaults to membership_rel. The interface for this function is:
function membership_rel.new ( rel_id membership_rels.rel_id%TYPE, @@ -245,42 +245,42 @@ creation_user acs_objects.creation_user%TYPE, creation_ip acs_objects.creation_ip%TYPE, ) return membership_rels.rel_id%TYPE; -membership_rel.ban sets the member_state of the given -rel_id to 'banned'. The interface for this procedure is:
+membership_rel.ban sets the member_state of the given +rel_id to 'banned'. The interface for this procedure is:
procedure membership_rel.ban ( rel_id membership_rels.rel_id%TYPE ); -membership_rel.approve sets the member_state of the -given rel_id to 'approved'. The interface for this procedure +
membership_rel.approve sets the member_state of the +given rel_id to 'approved'. The interface for this procedure is:
procedure membership_rel.approve ( rel_id membership_rels.rel_id%TYPE ); -membership_rel.reject sets the member_state of the given -rel_id to 'rejected. The interface for this procedure is:
+membership_rel.reject sets the member_state of the given +rel_id to 'rejected. The interface for this procedure is:
procedure membership_rel.reject ( rel_id membership_rels.rel_id%TYPE ); -membership_rel.unapprove sets the member_state of the -given rel_id to an empty string ''. The interface for this +
membership_rel.unapprove sets the member_state of the +given rel_id to an empty string ''. The interface for this procedure is:
procedure membership_rel.unapprove ( rel_id membership_rels.rel_id%TYPE ); -membership_rel.deleted sets the member_state of the -given rel_id to 'deleted'. The interface for this procedure +
membership_rel.deleted sets the member_state of the +given rel_id to 'deleted'. The interface for this procedure is:
procedure membership_rel.deleted ( rel_id membership_rels.rel_id%TYPE ); -membership_rel.delete deletes the given rel_id. The +
membership_rel.delete deletes the given rel_id. The interface for this procedure is:
procedure membership_rel.delete ( rel_id membership_rels.rel_id%TYPE ); -Composition Relationship
composition_rel.new creates a new composition relationship type -and returns the relationship's rel_id. All fields are optional -and default to null except for rel_type which defaults to +
Composition Relationship
composition_rel.new creates a new composition relationship type +and returns the relationship's rel_id. All fields are optional +and default to null except for rel_type which defaults to composition_rel. The interface for this function is:
function membership_rel.new ( rel_id composition_rels.rel_id%TYPE, @@ -290,15 +290,15 @@ creation_user acs_objects.creation_user%TYPE, creation_ip acs_objects.creation_ip%TYPE, ) return composition_rels.rel_id%TYPE; -composition_rel.delete deletes the given rel_id. The +
composition_rel.delete deletes the given rel_id. The interface for this procedure is:
procedure membership_rel.delete ( rel_id composition_rels.rel_id%TYPE ); -
- System creator
- System owner
- Documentation author -
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 08/22/2000 Rafael H. Schloming 0.2 Initial Revision 08/30/2000 Mark Thomas 0.3 Additional revisions; tried to clarify membership/compostion 09/08/2000 Mark Thomas View comments on this page at openacs.org +
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 08/22/2000 Rafael H. Schloming 0.2 Initial Revision 08/30/2000 Mark Thomas 0.3 Additional revisions; tried to clarify membership/compostion 09/08/2000 Mark Thomas View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/groups-requirements.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/groups-requirements.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/groups-requirements.html 29 Apr 2003 05:58:33 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/groups-requirements.html 7 May 2003 17:40:58 -0000 1.6.2.8 @@ -1,14 +1,14 @@ -OpenACS 4 Groups Requirements +
OpenACS 4 Groups Requirements by Rafael H. Schloming, Mark Thomas
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Almost all database-backed websites have users, and need to model the grouping of users. The OpenACS 4 Parties and Groups system is intended to provide the flexibility needed to model complex real-world organizational structures, particularly to support powerful subsite services; that is, where one OpenACS installation can support what appears to the user as distinct web services -for different user communities.
A powerful web service that can meet the needs of large enterprises must +for different user communities.
A powerful web service that can meet the needs of large enterprises must be able to model the the real world's very rich organizational structures and many ways of decomposing the same organization. For example, a corporation can be broken into structures (the corporation, its divisions, @@ -18,27 +18,27 @@ in a different sense) a particular office. OpenACS 4's Parties and Groups system will support such complex relations faithfully.
Historical Motivations
The primary limitation of the OpenACS 3.x user group system is that it restricts the application developer to representing a "flat group" -that contains only users: The user_groups table may contain the -group_id of a parent group, but parent-child relationship +that contains only users: The user_groups table may contain the +group_id of a parent group, but parent-child relationship support is limited because it only allows one kind of relationship between groups to be represented. Moreover, the Oracle database's limited support for tree-like structures makes the queries over these relationships expensive.
In addition, the Module Scoping design in OpenACS 3.0 introduced a party abstraction - a thing that is a person or a group of people - though not in the form of an explicit table. Rather, the triple of -scope, user_id, and group_id columns +scope, user_id, and group_id columns was used to identify the party. One disadvantage of this design convention is that it increases a data model's complexity by requiring the programmer to:
add these three columns to each "scoped" table
define a multi-column check constraint to protect against data corruption -(e.g., a row with a scope value of "group" but a null -group_id)
perform extra checks in Tcl and PL/SQL -functions and procedures to check both the user_id and -group_id values
In sum, the goal of the Parties and Groups system is to +(e.g., a row with a scope value of "group" but a null +group_id)
perform extra checks in Tcl and PL/SQL +functions and procedures to check both the user_id and +group_id values
In sum, the goal of the Parties and Groups system is to provide OpenACS programmers and site administrators with simple tools that fully describe the complex relationships that exist among groups in the real -world.
Pat Developer has a client project and wants to model the company, its offices, its divisions, and its departments as groups and the employees as -users.
We start with Groups, which contain members; the member can be either a person or another group (i.e. a member is a party).
In addition to membership, the party and groups system defines a composition relationship that may exist between groups: A @@ -72,7 +72,7 @@ GC. For example, the system should be able to enforce a rule like: Do not allow a party P to become a member of GC unless P is already -a member of GP.
The data model for the parties and groups system must provide support for +a member of GP.
The data model for the parties and groups system must provide support for the following types of entities:
- 10.0 Parties
A party is an entity used to represent either a @@ -118,7 +118,7 @@ GP.
60.10A group may be a component of multiple groups.
60.20A group as a component of itself is not supported.
60.30The data model must support component constraints.
60.40The data model should support the subclassing of -composition via OpenACS Relationships.
The API should let programmers accomplish the following tasks:
- 70.10 Create a group +composition via OpenACS Relationships.
The API should let programmers accomplish the following tasks:
- 70.10 Create a group
The parties and groups system provides a well defined API call that creates a new group by running the appropriate transactions on the parties @@ -219,7 +219,7 @@
Since many SQL queries will check membership in a group as part of the -where clause, whatever mechanism is used to check membership in SQL -should be fairly small and simple.
The user interface is a set of HTML pages that are used to drive the underlying API. The user interface may provide the following functions:
200.0 Create a party
210.0 View the attributes of a party
220.0 Update the attributes of a party
240.0 Delete a party
250.0 Add a party to a group
260.0 Remove a party from a group
270.0 Perform the membership and composition checks -outlined in 130.x to 165.x
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 08/16/2000 Rafael Schloming 0.2 Initial revision 08/19/2000 Mark Thomas 0.3 Edited and reviewed, conforms to requirements template 08/23/2000 Kai Wu 0.4 Further revised, added UI requirements 08/24/2000 Mark Thomas 0.5 Final edits, pending freeze 08/24/2000 Kai Wu 0.6 More revisions, added composition requirements 08/30/2000 Mark Thomas 0.7 More revisions, added composition requirements 09/08/2000 Mark Thomas View comments on this page at openacs.org +outlined in 130.x to 165.x
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 08/16/2000 Rafael Schloming 0.2 Initial revision 08/19/2000 Mark Thomas 0.3 Edited and reviewed, conforms to requirements template 08/23/2000 Kai Wu 0.4 Further revised, added UI requirements 08/24/2000 Mark Thomas 0.5 Final edits, pending freeze 08/24/2000 Kai Wu 0.6 More revisions, added composition requirements 08/30/2000 Mark Thomas 0.7 More revisions, added composition requirements 09/08/2000 Mark Thomas View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/index.html,v diff -u -r1.6.2.9 -r1.6.2.10 --- openacs-4/packages/acs-core-docs/www/index.html 4 May 2003 06:30:02 -0000 1.6.2.9 +++ openacs-4/packages/acs-core-docs/www/index.html 7 May 2003 17:40:58 -0000 1.6.2.10 @@ -1,2 +1,2 @@ -OpenACS Documentation Table of Contents
- I. OpenACS For Everyone
- II. Administrator's Guide
- III. For OpenACS Package Developers
- 8. Development Tutorial
- 9. Development Reference
- OpenACS 4.6.3 Packages
- OpenACS 4.6.3 Data Models and the Object System
- The Request Processor
- The OpenACS Database Access API
- Using Templates in OpenACS 4.6.3
- Groups, Context, Permissions
- Writing OpenACS 4.6.3 Application Pages
- Parties in OpenACS 4.6.3
- OpenACS 4.x Permissions Tediously Explained
- Object Identity
- Programming with AOLserver
- 10. Engineering Standards
- IV. For OpenACS Platform Developers
- 11. Kernel Documentation
- Overview
- OpenACS 4 Object Model Requirements
- OpenACS 4 Object Model Design
- OpenACS 4 Permissions Requirements
- OpenACS 4 Permissions Design
- OpenACS 4 Groups Requirements
- OpenACS 4 Groups Design
- OpenACS 4 Subsites Requirements
- OpenACS 4 Subsites Design Document
- OpenACS 4.6.3 Package Manager Requirements
- OpenACS 4.6.3 Package Manager Design
- Database Access API
- OpenACS 4 Security Requirements
- OpenACS 4 Security Design
- OpenACS 4 Security Notes
- OpenACS 4 Request Processor Requirements
- OpenACS 4 Request Processor Design
- Documenting Tcl Files: Page Contracts and Libraries
- Bootstrapping OpenACS
List of Figures
View comments on this page at openacs.org +OpenACS Documentation Table of Contents
- I. OpenACS For Everyone
- II. Administrator's Guide
- III. For OpenACS Package Developers
- 8. Development Tutorial
- 9. Development Reference
- OpenACS 4.6.3 Packages
- OpenACS 4.6.3 Data Models and the Object System
- The Request Processor
- The OpenACS Database Access API
- Using Templates in OpenACS 4.6.3
- Groups, Context, Permissions
- Writing OpenACS 4.6.3 Application Pages
- Parties in OpenACS 4.6.3
- OpenACS 4.x Permissions Tediously Explained
- Object Identity
- Programming with AOLserver
- 10. Engineering Standards
- IV. For OpenACS Platform Developers
- 11. Kernel Documentation
- Overview
- OpenACS 4 Object Model Requirements
- OpenACS 4 Object Model Design
- OpenACS 4 Permissions Requirements
- OpenACS 4 Permissions Design
- OpenACS 4 Groups Requirements
- OpenACS 4 Groups Design
- OpenACS 4 Subsites Requirements
- OpenACS 4 Subsites Design Document
- OpenACS 4.6.3 Package Manager Requirements
- OpenACS 4.6.3 Package Manager Design
- Database Access API
- OpenACS 4 Security Requirements
- OpenACS 4 Security Design
- OpenACS 4 Security Notes
- OpenACS 4 Request Processor Requirements
- OpenACS 4 Request Processor Design
- Documenting Tcl Files: Page Contracts and Libraries
- Bootstrapping OpenACS
List of Figures
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/individual-programs.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/individual-programs.html,v diff -u -r1.1.2.7 -r1.1.2.8 --- openacs-4/packages/acs-core-docs/www/individual-programs.html 4 May 2003 06:30:02 -0000 1.1.2.7 +++ openacs-4/packages/acs-core-docs/www/individual-programs.html 7 May 2003 17:40:58 -0000 1.1.2.8 @@ -1,15 +1,15 @@ -Individual Programs
OpenACS 4.6.3.�The OpenACS tarball comprises the core packages and +
Individual Programs
OpenACS 4.6.3.�The OpenACS tarball comprises the core packages and many useful additional packages. This includes a full set of documentation. The tarball works with both PostGreSQL and Oracle.
Operating System.�OpenACS is designed for a Unix-like system. It is developed primarily in Linux. It can be run on Mac OS X, - and in Windows within VMWare.
Linux.�the section called “Install Linux and supporting software”. The installation assumes a linux kernel of 2.2.22 or newer, or 2.4.14 or newer.
FreeBSD.�FreeBSD + and in Windows within VMWare.
Linux.�Section�, “Install Linux and supporting software”. The installation assumes a linux kernel of 2.2.22 or newer, or 2.4.14 or newer.
FreeBSD.�FreeBSD guide. The Reference Platform uses bash, which is the standard Linux shell. If you are using a different shell, you will need to substitute your shell's conventions for setting environment variables when - appropriate.
Mac OS X.�the section called “OpenACS Installation Guide for Mac OS X”
Windows/VMWare.�OpenACS Installation Guide for Windows 2000 The only + appropriate.
Mac OS X.�Section�, “OpenACS Installation Guide for Mac OS X”
Windows/VMWare.�OpenACS Installation Guide for Windows 2000 The only way to run OpenACS on Windows is through the VMWare emulator. (Please let me know if you have OpenACS running directly in Windows.)
Build Environment.�The Reference Platform installation compiles most programs from @@ -19,20 +19,20 @@ operating system distribution.
GNU Make 3.76.1 or newer, REQUIRED.�PostgreSQL and AOLserver require gmake to compile. Note that on most linux distributions, GNU Make is simply named - make and + make and there is no - gmake, + gmake, whereas on BSD distributions, - make and - gmake are + make and + gmake are different.
TCL 8.3.�
TCL 8.3 development headers and libraries, OPTIONAL.� The site-wide-search service, OpenFTS, requires these to - compile. (Debian users: apt-get install + compile. (Debian users: apt-get install tcl8.3-dev). You need this to install OpenFTS.
libxml2 and libxml2-devel, REQUIRED.� OpenACS 4.6.3 stores queries in XML files, so we use an AOLserver module called nsxml to parse these files. libxml2-devel is required to compile nsxml. Libxml2 is available from http://xmlsoft.org). On Debian, - this can be installed by doing apt-get install + this can be installed by doing apt-get install libxml2-dev. Users of other distributions can download rpms from rpmfind.net.
Web Server.�The web server handles incoming HTTP requests, provides a runtime environment for OpenACS's tcl code, connects to the @@ -65,14 +65,14 @@
nsxml is available at http://acs-misc.sourceforge.net.
- The patch that makes exec work + The patch that makes exec work on BSD is available at sourceforge.net
- The patch that makes ns_uuencode + The patch that makes ns_uuencode work for binary files is available at sourceforge.net
The patch that makes AOLserver respect the - -g flag is available at + -g flag is available at sourceforge.net
AolServer startup wrapper Version 1, REQUIRED.�This file automates the startup of AOLserver. You need Index: openacs-4/packages/acs-core-docs/www/install-overview.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/install-overview.html,v diff -u -r1.7.2.8 -r1.7.2.9 --- openacs-4/packages/acs-core-docs/www/install-overview.html 4 May 2003 06:30:02 -0000 1.7.2.8 +++ openacs-4/packages/acs-core-docs/www/install-overview.html 7 May 2003 17:40:58 -0000 1.7.2.9 @@ -1,17 +1,17 @@ -
Overview +
Overview by Vinod Kurup
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -According to Philip Greenspun:
- “The ArsDigita Community System (ACS) is a toolkit of software + “The ArsDigita Community System (ACS) is a toolkit of software that will help you build Web services with a collaborative dimension, ranging from knowledge management within companies to B2C ecommerce to product support and community among the customers. The software is free and open-source and has been tested in heavy use since - 1995.” + 1995.”
What's OpenACS? OpenACS was born when Don Baccus, Ben Adida, et al decided to port ACS from Oracle to @@ -25,7 +25,7 @@ the word) to extend it to other databases. Don Baccus leads the development and numerous developers (and non-developers) contribute from around the world. -
This document will describe how to install, configure, and maintain an installation of OpenACS 4.6.3 on a Unix-like @@ -34,11 +34,11 @@ OpenACS 4.6.3-O Reference Platform, which use Red Hat 8.0. Differences between the Reference Platform and common alternate platforms are noted where known. -
You will need a PC (or equivalent) with at least these minimum requirements:
Pentium processor
128 MB RAM - (much more if you want Oracle)
4 GB hard drive
You will need all of the required Chapter�2.
+ (much more if you want Oracle)
4 GB hard drive
You will need all of the required Chapter�2, Prerequisite Software.
If you want to serve pages to people outside of your machine, you'll need a network connection of some type.
@@ -57,8 +57,8 @@
(For Oracle) Starting an X server and running an X program remotely
- Basic file management using cp, rm, - mv, and cd + Basic file management using cp, rm, + mv, and cd
Compiling a program using ./config and make.
@@ -70,37 +70,37 @@ All of the software that you will need is free and open-source, except for Oracle. You can obtain a free copy of Oracle for development purposes. This is described in the Acquire Oracle section. -
The basic steps to getting OpenACS up and running are:
Install an OS
Install a webserver (AOLServer)
Install a database (Oracle or PostgreSQL)
Install a database driver (allows the webserver to talk to the database) -
Start the OpenACS installer, which will configure a database instance..
This is text you will see on - screen, such as a Button or link - in a radio button list or menu.
This is text that you will type.
This is text from a program or file which you may need to +
Start the OpenACS installer, which will configure a database instance..
This is text you will see on + screen, such as a Button or link + in a radio button list or menu.
This is text that you will type.
This is text from a program or file which you may need to examine or edit:
if {$database == "oracle"} { set db_password "mysitepassword" }This is text that you will -see and type in a command shell, including text you may have to -change. It is followed by a list of just the commands, -which you can copy and paste.
[root@localhost root]# su - nsadmin -[nsadmin@localhost aolserver]$ svc -d /service/server1 -[nsadmin@localhost aolserver]$ dropdb server1 +see and type in a command shell, including text you may have to +change. It is followed by a list of just the commands, +which you can copy and paste.[root@localhost root]# su - nsadmin +[nsadmin@localhost aolserver]$ svc -d /service/server1 +[nsadmin@localhost aolserver]$ dropdb server1 DROP DATABASE -[nsadmin@localhost aolserver]$ createdb server1 +[nsadmin@localhost aolserver]$ createdb server1 CREATE DATABASE -su - nsadmin -svc -d /service/server1 -dropdb server1 -createdb server1We'll do our best to assure that following our instructions will get you to the promised land. If something goes wrong, don't panic. There are plenty of ways to get help. Here are some tips:
Keep track of the commands you are run and record their output. I like to do my installations in a shell inside of emacs - (M-x shell) so that I can save + (M-x shell) so that I can save the output if needed. An alternative would be to use the - script command. + script command.
We'll point out where the error logs for the various pieces of software are. Output from those logs will help us help you. Don't @@ -131,7 +131,7 @@ If you find errors in this document or if you have ideas about making it better, please post them in our BugTracker. -
After reading through this tome, you may ask yourself if there is a better way. Well, not quite. Jonathan Marsden has created RPMs (at @@ -140,7 +140,7 @@ 4.6.3. There has been talk about automating the install process, but that hasn't happened yet. Stay tuned! -
This document was created by Vinod Kurup, but it's really just plagiarism from a number of documents that came before it. If I've used something that you've written without proper credit, let me @@ -161,7 +161,7 @@ Aufrecht's OpenACS 4.5 Quick Guide.
Please also see the Credits section for more acknowledgements. -
Here's a list of some helpful documentation for various OS's
Once you get your OS installed, it's imperative that you secure your installation. As Jon Griffin repeatedly warns us, "No distribution is secure out of the box." The Reference Platform implements @@ -207,9 +207,9 @@
Bruce Schneier's Crypto-Gram, especially The - security patch treadmill and Monitoring First.
+ security patch treadmill and Monitoring First.
Here are some resources that OpenACS users have found useful. -
+
Philip and Alex's Guide to Web Publishing - A very readable @@ -242,7 +242,7 @@ Linux in a Nutshell -
The UNIX Reference Desk Index: openacs-4/packages/acs-core-docs/www/install-redhat.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/install-redhat.html,v diff -u -r1.1.2.7 -r1.1.2.8 --- openacs-4/packages/acs-core-docs/www/install-redhat.html 4 May 2003 06:30:02 -0000 1.1.2.7 +++ openacs-4/packages/acs-core-docs/www/install-redhat.html 7 May 2003 17:40:58 -0000 1.1.2.8 @@ -1,5 +1,5 @@ -
Appendix�A.�Install Red Hat 8.0 +
Appendix�A.�Install Red Hat 8.0 by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. @@ -8,38 +8,38 @@ you can reformat and you want to be sure that your installation works and is secure; it should take about an hour. You can skip this section if you already have a machine ready with this - software (see the section called “Individual Programs” for details):
libxml2
tcl
gmake and the compile and build environment.
and these optional items
emacs
cvs
ImageMagick
DocBook and supporting software
(In my experience, it's almost always a net time savings of several hours to install a new machine from scratch compared to installing each of these packages installed independently.)
Unplug the network cable from your + software (see Section�, “Individual Programs” for details):
libxml2
tcl
gmake and the compile and build environment.
and these optional items
emacs
cvs
ImageMagick
DocBook and supporting software
(In my experience, it's almost always a net time savings of several hours to install a new machine from scratch compared to installing each of these packages installed independently.)
Unplug the network cable from your computer. We don't want to connect to the network until we're sure the computer is secure. - + (Wherever you see the word secure, you should always read it as, "secure enough for our purposes, given the amount of work we're willing to exert and the estimated risk and consequences.")
Insert Red Hat 8.0 Disk 1 into the CD-ROM and reboot the computer
At the - boot: + boot: prompt, press Enter for a graphical install. The text install is fairly different, so if you need to do that instead proceed with caution, because the guide won't match the steps.
Checking the media is probably a waste of time, so when it asks press Tab and - then Enter to skip it.
After the graphical introduction page loads, click Next
Choose the language you want to use and then click -Next -
Select the keyboard layout you will use and Click Next
Choose your mouse type and Click Next
Red Hat has several templates for new + then Enter to skip it.
After the graphical introduction page loads, click Next
Choose the language you want to use and then click +Next +
Select the keyboard layout you will use and Click Next
Choose your mouse type and Click Next
Red Hat has several templates for new computers. We'll start with the "Server" template and then fine-tune it during the rest of the install. Choose - Server + Server and click - Next.
Reformat the hard drive. If you know what you're doing, + Next.
Reformat the hard drive. If you know what you're doing, do this step on your own. Otherwise: we're going to let the installer wipe out the everything on the main hard drive and then arrange things to - its liking.
Choose Automatically Partition - and click Next
Uncheck -Review (and modify if needed) the partitions created and click Next
On the pop-up window asking "Are you sure + its liking.
Choose Automatically Partition + and click Next
Uncheck +Review (and modify if needed) the partitions created and click Next
On the pop-up window asking "Are you sure you want to do this?" click - Yes - IF YOU ARE WIPING YOUR HARD DRIVE.
Click Next on the boot loader screen
Configure Networking. + Yes + IF YOU ARE WIPING YOUR HARD DRIVE.
Click Next on the boot loader screen
Configure Networking. Again, if you know what you're doing, do this step yourself, being sure to note the firewall holes. Otherwise, follow the instructions in this step to set up a computer directly connected to the internet with a dedicated IP address.
DHCP is a system by which a computer that @@ -48,31 +48,31 @@ IP address (if it doesn't, it will be tricky to access the OpenACS service from the outside world), we're going to set up that address. If you don't know your netmask, 255.255.255.0 is usually a pretty safe -guess. Click Edit, uncheck Configure using DHCP -and type in your IP and netmask. Click Ok.
Type in your host -name, gateway, and DNS server(s). Then click Next.
We're going to use the firewall template for high +guess. Click Edit, uncheck Configure using DHCP +and type in your IP and netmask. Click Ok.
Type in your host +name, gateway, and DNS server(s). Then click Next.
We're going to use the firewall template for high security, meaning that we'll block almost all incoming traffic. Then we'll add a few holes to the firewall for services which we need and -know are secure. Choose High +know are secure. Choose High security level. Check -WWW, -SSH, and -Mail (SMTP). In the Other ports -box, enter 443, 8000, 8443. Click -Next. -Port 443 is for https (http over ssl), and 8000 and 8443 are http and https access to the development server we'll be setting up.
Select any additional languages you want the +WWW, +SSH, and +Mail (SMTP). In the Other ports +box, enter 443, 8000, 8443. Click +Next. +Port 443 is for https (http over ssl), and 8000 and 8443 are http and https access to the development server we'll be setting up.
Select any additional languages you want the computer to support and then click - Next
Choose your time zone and click Next.
Type in a root + Next
Choose your time zone and click Next.
Type in a root password, twice. To improve security, we're going to prevent anyone from connecting to the computer directly as root. Instead, we'll create a different user, called - remadmin, used solely to + remadmin, used solely to connect to the computer for administration. Click -Add -and enter username remadmin and a password, -twice, then click OK. Then click -Next.
On the Package selection page, we're going to +Add +and enter username remadmin and a password, +twice, then click OK. Then click +Next.
On the Package selection page, we're going to uncheck a lot of packages that install software we don't need, and add packages that have stuff we do need. You should install everything we're installing here or the guide may not work for you; you can @@ -81,82 +81,82 @@ risk that's still screened by the firewall, or a resource hog. Just don't install a database or web server, because that would conflict with the database and web server we'll install later. -
check�Editors�(this�installs�emacs),
-click�Details�next�to�Text-based�Internet,�check�lynx,�and�click�OK;
-check�Authoring�and�Publishing�(this�installs�docbook),
-uncheck�Server�Configuration�Tools,
-uncheck�Web�Server,
-uncheck�Windows�File�Server,
-check�Development�Tools�(this�installs�gmake�and�other�build�tools),
-uncheck�Administration�Tools,�and
-uncheck�Printing�Support.�At the bottom, check Select Individual Packages and click Next
We need to fine-tune the exact list of packages. +
check�Editors�(this�installs�emacs),
+click�Details�next�to�Text-based�Internet,�check�lynx,�and�click�OK;
+check�Authoring�and�Publishing�(this�installs�docbook),
+uncheck�Server�Configuration�Tools,
+uncheck�Web�Server,
+uncheck�Windows�File�Server,
+check�Development�Tools�(this�installs�gmake�and�other�build�tools),
+uncheck�Administration�Tools,�and
+uncheck�Printing�Support.�At the bottom, check Select Individual Packages and click Next
We need to fine-tune the exact list of packages. The same rules apply as in the last step - you can add more stuff, but you shouldn't remove anything the guide adds. We're going to go through all the packages in one big list, so select -Flat -View and wait. In a minute, a -list of packages will appear.
uncheck�apmd�(monitors�power,�not�very�useful�for�servers),�
-check�ImageMagick�(required�for�the�photo-album�packages,�
-uncheckisdn4k-utils�(unless�you�are�using�isdn,�this�installs�a�useless�daemon),�
-check�mutt�(a�mail�program�that�reads�Maildir),
-uncheck�nfs-utils�(nfs�is�a�major�security�risk),�
-uncheck�pam-devel�(I�don't�remember�why,�but�we�don't�want�this),�
-uncheck�portmap,�
-uncheck�postfix�(this�is�an�MTA,�but�we're�going�to�install�qmail�later),�
-uncheck�rsh�(rsh�is�a�security�hole),�
-uncheck�sendmail�(sendmail�is�an�insecure�MTA;�we're�going�to�install�qmail�instead�later),
-check�tcl�(we�need�tcl),�and�
-uncheck�xinetd�(xinetd�handles�incoming�tcp�connections.��We'll�install�a�different,�more�secure�program,�ucspi-tcp).
-Click�NextRed Hat isn't completely happy with the combination +Flat +View and wait. In a minute, a +list of packages will appear.
uncheck�apmd�(monitors�power,�not�very�useful�for�servers),�
+check�ImageMagick�(required�for�the�photo-album�packages,�
+uncheckisdn4k-utils�(unless�you�are�using�isdn,�this�installs�a�useless�daemon),�
+check�mutt�(a�mail�program�that�reads�Maildir),
+uncheck�nfs-utils�(nfs�is�a�major�security�risk),�
+uncheck�pam-devel�(I�don't�remember�why,�but�we�don't�want�this),�
+uncheck�portmap,�
+uncheck�postfix�(this�is�an�MTA,�but�we're�going�to�install�qmail�later),�
+uncheck�rsh�(rsh�is�a�security�hole),�
+uncheck�sendmail�(sendmail�is�an�insecure�MTA;�we're�going�to�install�qmail�instead�later),
+check�tcl�(we�need�tcl),�and�
+uncheck�xinetd�(xinetd�handles�incoming�tcp�connections.��We'll�install�a�different,�more�secure�program,�ucspi-tcp).
+Click�NextRed Hat isn't completely happy with the combination of packages we've selected, and wants to satisfy some dependencies. Don't let it. On the next screen, choose -Ignore Package -Dependencies and click -Next. +Ignore Package +Dependencies and click +Next.
Click - Next + Next to start the copying of files.
Wait. Insert Disk 2 when asked.
Wait. Insert Disk 3 when asked.
If you know how to use it, create a boot disk. Since you can also boot into recovery mode with the Install CDs, this is less useful than it used to be, and we - won't bother. Select No,I do not want to create a boot disk and click Next.
Click Exit, remove the CD, and watch the + won't bother. Select No,I do not want to create a boot disk and click Next.
Click Exit, remove the CD, and watch the computer reboot.
After it finishes rebooting and shows the login - prompt, log in:
yourserver login: root + prompt, log in:yourserver login: root Password: -[root@yourserver root]#Lock down SSH
Lock down SSH
SSH is the protocol we use to connect securely to the computer (replacing telnet, which is insecure). sshd is the daemon that listens for incoming ssh connections. As a security precaution, we are now going to tell ssh not to allow anyone to connect directly to this computer as root. Type this into the shell: -
emacs /etc/ssh/sshd_configSearch�for�the�word�"root"�by�typing�C-s�(that's�emacs-speak�for�control-s)�and�then�root.���
-Change�the�line�#PermitRootLogin�yes�to�PermitRootLogin�no�and�save�and�exit�by�typing�C-x�C-s�C-x�C-c- Restart sshd so that the change takes effect.
service sshd restartRed Hat still installed a few services we -don't need, and which can be security holes. Use the service command to turn them off, and then use chkconfig to automatically edit the System V init directories to permanently (The System V init directories are the ones in /etc/rc.d. They consist of a bunch of scripts for starting and stopping programs, and directories of symlinks for each system level indicating which services should be up and down at any given service level. We'll use this system for PostGreSQL, but we'll use daemontools to perform a similar function for AOLServer. (The reason for this discrepencies is that, while daemontools is better, it's a pain in the ass to deal with and nobody's had any trouble leaving PostGreSQL the way it is.)
[root@yourserver root]# service pcmcia stop -[root@yourserver root]# service netfs stop -[root@yourserver root]# chkconfig --del pcmcia -[root@yourserver root]# chkconfig --del netfs +emacs /etc/ssh/sshd_configSearch�for�the�word�"root"�by�typing�C-s�(that's�emacs-speak�for�control-s)�and�then�root.���
+Change�the�line�#PermitRootLogin�yes�to�PermitRootLogin�no�and�save�and�exit�by�typing�C-x�C-s�C-x�C-c- Restart sshd so that the change takes effect.
service sshd restartRed Hat still installed a few services we +don't need, and which can be security holes. Use the service command to turn them off, and then use chkconfig to automatically edit the System V init directories to permanently (The System V init directories are the ones in /etc/rc.d. They consist of a bunch of scripts for starting and stopping programs, and directories of symlinks for each system level indicating which services should be up and down at any given service level. We'll use this system for PostGreSQL, but we'll use daemontools to perform a similar function for AOLServer. (The reason for this discrepencies is that, while daemontools is better, it's a pain in the ass to deal with and nobody's had any trouble leaving PostGreSQL the way it is.)
[root@yourserver root]# service pcmcia stop +[root@yourserver root]# service netfs stop +[root@yourserver root]# chkconfig --del pcmcia +[root@yourserver root]# chkconfig --del netfs [root@yourserver root]# -service pcmcia stop +service pcmcia stop service netfs stop chkconfig --del pcmcia -chkconfig --del netfs
Plug in the network cable.
Verify that you have connectivity by going to another +chkconfig --del netfs
Plug in the network cable.
Verify that you have connectivity by going to another computer and ssh'ing to - yourserver, logging in as - remadmin, and promoting yourself to root:
[joeuser@someotherserver]$ ssh remadmin@yourserver.test + yourserver, logging in as + remadmin, and promoting yourself to root:[joeuser@someotherserver]$ ssh remadmin@yourserver.test The authenticity of host 'yourserver.test (1.2.3.4)' can't be established. DSA key fingerprint is 10:b9:b6:10:79:46:14:c8:2d:65:ae:c1:61:4b:a5:a5. -Are you sure you want to continue connecting (yes/no)? yes +Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'yourserver.test (1.2.3.4)' (DSA) to the list of known hosts. Password: Last login: Mon Mar 3 21:15:27 2003 from host-12-01.dsl-sea.seanet.com -[remadmin@yourserver remadmin]$ su - +[remadmin@yourserver remadmin]$ su - Password: [root@yourserver root]#
Upgrade the kernel to fix a security hole. The default Red Hat 8.0 system kernel (2.4.18-14, which you can check - with uname -a) has several security problems. Download the new kernel, install it, and reboot.
[root@yourserver root]# cd /tmp -[root@yourserver tmp]# wget http://updates.redhat.com/7.1/en/os/i686/kernel-2.4.18-27.7.x.i686.rpm + with uname -a) has several security problems. Download the new kernel, install it, and reboot.[root@yourserver root]# cd /tmp +[root@yourserver tmp]# wget http://updates.redhat.com/7.1/en/os/i686/kernel-2.4.18-27.7.x.i686.rpm --20:39:00-- http://updates.redhat.com/7.1/en/os/i686/kernel-2.4.18-27.7.x.i686.rpm => `kernel-2.4.18-27.7.x.i686.rpm' Resolving updates.redhat.com... done. @@ -168,17 +168,17 @@ 20:41:39 (78.38 KB/s) - `kernel-2.4.18-27.7.x.i686.rpm' saved [12736430/12736430] -root@yourserver tmp]# rpm -Uvh kernel-2.4.18-27.7.x.i686.rpm +root@yourserver tmp]# rpm -Uvh kernel-2.4.18-27.7.x.i686.rpm warning: kernel-2.4.18-27.7.x.i686.rpm: V3 DSA signature: NOKEY, key ID db42a60e Preparing... ########################################### [100%] 1:kernel ########################################### [100%] -[root@yourserver tmp]# reboot +[root@yourserver tmp]# reboot Broadcast message from root (pts/0) (Sat May 3 20:46:39 2003): The system is going down for reboot NOW! [root@yourserver tmp]# -cd /tmp +cd /tmp wget http://updates.redhat.com/7.1/en/os/i686/kernel-2.4.18-27.7.x.i686.rpm rpm -Uvh kernel-2.4.18-27.7.x.i686.rpm -reboot
View comments on this page at openacs.org +rebootView comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/kernel-doc.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/kernel-doc.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/kernel-doc.html 29 Apr 2003 05:58:33 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/kernel-doc.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,2 +1,2 @@ -Chapter�11.�Kernel Documentation Table of Contents
- Overview
- OpenACS 4 Object Model Requirements
- OpenACS 4 Object Model Design
- OpenACS 4 Permissions Requirements
- OpenACS 4 Permissions Design
- OpenACS 4 Groups Requirements
- OpenACS 4 Groups Design
- OpenACS 4 Subsites Requirements
- OpenACS 4 Subsites Design Document
- OpenACS 4.6.3 Package Manager Requirements
- OpenACS 4.6.3 Package Manager Design
- Database Access API
- OpenACS 4 Security Requirements
- OpenACS 4 Security Design
- OpenACS 4 Security Notes
- OpenACS 4 Request Processor Requirements
- OpenACS 4 Request Processor Design
- Documenting Tcl Files: Page Contracts and Libraries
- Bootstrapping OpenACS
View comments on this page at openacs.org +Chapter�11.�Kernel Documentation Table of Contents
- Overview
- OpenACS 4 Object Model Requirements
- OpenACS 4 Object Model Design
- OpenACS 4 Permissions Requirements
- OpenACS 4 Permissions Design
- OpenACS 4 Groups Requirements
- OpenACS 4 Groups Design
- OpenACS 4 Subsites Requirements
- OpenACS 4 Subsites Design Document
- OpenACS 4.6.3 Package Manager Requirements
- OpenACS 4.6.3 Package Manager Design
- Database Access API
- OpenACS 4 Security Requirements
- OpenACS 4 Security Design
- OpenACS 4 Security Notes
- OpenACS 4 Request Processor Requirements
- OpenACS 4 Request Processor Design
- Documenting Tcl Files: Page Contracts and Libraries
- Bootstrapping OpenACS
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/kernel-overview.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/kernel-overview.html,v diff -u -r1.3.2.7 -r1.3.2.8 --- openacs-4/packages/acs-core-docs/www/kernel-overview.html 29 Apr 2003 05:58:33 -0000 1.3.2.7 +++ openacs-4/packages/acs-core-docs/www/kernel-overview.html 7 May 2003 17:40:59 -0000 1.3.2.8 @@ -1,5 +1,5 @@ -Overview +
Overview Compared to its predecessors, version 4.6.3 of OpenACS has a much more structured organization, i.e. the most significant change is found at the system architecture level, Index: openacs-4/packages/acs-core-docs/www/linux-installation.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/Attic/linux-installation.html,v diff -u -r1.1.2.7 -r1.1.2.8 --- openacs-4/packages/acs-core-docs/www/linux-installation.html 4 May 2003 06:30:02 -0000 1.1.2.7 +++ openacs-4/packages/acs-core-docs/www/linux-installation.html 7 May 2003 17:40:59 -0000 1.1.2.8 @@ -1,103 +1,103 @@ -
Install Linux and supporting software +
Install Linux and supporting software by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Figure�3.1.�Assumptions in this section
None of these locations are set in stone - they're simply the values that we've chosen. The values that you'll probably want to change, such as service name, are - marked like this. The other + marked like this. The other values we recommend you leave unchanged unless you have a reason to change them.
Note
Some of the paths and user accounts have been changed from those recommended in previous versions of this document to improve security and maintainability. See this thread for discussion. -
You will need a PC running linux with the following software installed:
libxml2
tcl
gmake and the compile and build environment.
and optionally this software:
emacs
cvs
ImageMagick
DocBook and supporting software
You can follow the walkthrough of the - Red Hat 8.0 Install for OpenACS.
You will need a PC running linux with the following software installed:
libxml2
tcl
gmake and the compile and build environment.
and optionally this software:
emacs
cvs
ImageMagick
DocBook and supporting software
You can follow the walkthrough of the + Red Hat 8.0 Install for OpenACS.
This section assumes that the source tarballs for supporting + software are in /tmp. It assumes that you begin each continuous block of commands as root, and you should end each block as root. It doesn't care which directory - you start in. Text instructions always precede the commands they refer to.
The OpenACS tarball contains sample configuration files + you start in. Text instructions always precede the commands they refer to.
The OpenACS tarball contains sample configuration files for some of the packages listed below. In order to access those - files, unpack the tarball now.
[root@yourserver root]# cd /tmp -[root@yourserver tmp]# tar xzf openacs-4.6.3.tgz -cd /tmp -tar xzf openacs-4.6.3.tgzCVS is a source control system. Create and initialize a - directory for a local cvs repository.
[root@yourserver tmp]# mkdir /cvsroot -[root@yourserver tmp]# cvs -d /cvsroot init + files, unpack the tarball now.[root@yourserver root]# cd /tmp +[root@yourserver tmp]# tar xzf openacs-4.6.3.tgz +cd /tmp +tar xzf openacs-4.6.3.tgz
CVS is a source control system. Create and initialize a + directory for a local cvs repository.
[root@yourserver tmp]# mkdir /cvsroot +[root@yourserver tmp]# cvs -d /cvsroot init [root@yourserver tmp]# -mkdir /cvsroot -cvs -d /cvsroot initIf you plan to write or edit any documentation with emacs, install a customized emacs configuration file with DocBook commands in the skeleton directory, so it will be used for all new users. The file also fixes the backspace -> help mis-mapping that often occurs in - terminals.
[root@yourserver tmp]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/emacs.txt /etc/skel/.emacs -cp: overwrite `/etc/skel/.emacs'? y -[root@yourserver tmp]#Daemontools is a collection of programs for controlling + terminals.
[root@yourserver tmp]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/emacs.txt /etc/skel/.emacs +cp: overwrite `/etc/skel/.emacs'? y +[root@yourserver tmp]#Daemontools is a collection of programs for controlling other processes. We use daemontools to run and monitor AOLServer. It is installed in /package. These commands install daemontools and svgroup. svgroup is a script for granting permissions, to allow users other than root to use daemontools for specific - services.
Install Daemontools
Red Hat
Make sure you have the source tarball in - /tmp, or download it. (The -p + services.
Install Daemontools
Red Hat
Make sure you have the source tarball in + /tmp, or download it. (The -p flag in mkdir causes all implied directories in the path - to be made as well.)
(If you are using Red Hat 9.0, you need to put #include <errno.h> as the first line of /package/admin/daemontools-0.76/src/error.h. More information)
[root@yourserver root]# mkdir -p /package -[root@yourserver root]# chmod 1755 /package/ -[root@yourserver root]# cd /package/ -[root@yourserver package]# tar xzf /tmp/daemontools-0.76.tar.gz -[root@yourserver package]# cd admin/daemontools-0.76/ -[root@yourserver daemontools-0.76]# package/install + to be made as well.)(If you are using Red Hat 9.0, you need to put #include <errno.h> as the first line of /package/admin/daemontools-0.76/src/error.h. More information)
[root@yourserver root]# mkdir -p /package +[root@yourserver root]# chmod 1755 /package/ +[root@yourserver root]# cd /package/ +[root@yourserver package]# tar xzf /tmp/daemontools-0.76.tar.gz +[root@yourserver package]# cd admin/daemontools-0.76/ +[root@yourserver daemontools-0.76]# package/install Linking ./src/* into ./compile... (many lines omitted) Creating /service... Adding svscanboot to inittab... init should start svscan now. [root@yourserver root]# -mkdir -p /package +mkdir -p /package chmod 1755 /package cd /package tar xzf /tmp/daemontools-0.76.tar.gz cd admin/daemontools-0.76 -package/install
Debian
root:~# apt-get install daemontools-installer +package/installDebian
root:~# apt-get install daemontools-installer root:~# build-daemontoolsVerify that svscan is running. If it is, you should see - these two processes running:
[root@yourserver root]# ps -auxw | grep service + these two processes running:[root@yourserver root]# ps -auxw | grep service root 13294 0.0 0.1 1352 272 ? S 09:51 0:00 svscan /service root 13295 0.0 0.0 1304 208 ? S 09:51 0:00 readproctitle service errors: ....................................... [root@yourserver root]#Install a script to grant non-root users permission to - control daemontools services.
[root@yourserver root]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/svgroup.txt /usr/local/bin/svgroup -[root@yourserver root]# chmod 755 /usr/local/bin/svgroup -cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/svgroup.txt /usr/local/bin/svgroup -chmod 755 /usr/local/bin/svgroupQmail is a Mail Transfer Agent. It handles incoming and outgoing mail. Install qmail if you want your OpenACS server to send and receive mail, and you don't want to use an alternate MTA.
Install ucspi.�This program handles incoming tcp connections. - Download ucspi and install it.
[root@yourserver root]# cd /usr/local/src -[root@yourserver src]# tar xzf /tmp/ucspi-tcp-0.88.tar.gz -[root@yourserver src]# cd ucspi-tcp-0.88 -[root@yourserver ucspi-tcp-0.88]# make + control daemontools services.[root@yourserver root]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/svgroup.txt /usr/local/bin/svgroup +[root@yourserver root]# chmod 755 /usr/local/bin/svgroup +cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/svgroup.txt /usr/local/bin/svgroup +chmod 755 /usr/local/bin/svgroup
Qmail is a Mail Transfer Agent. It handles incoming and outgoing mail. Install qmail if you want your OpenACS server to send and receive mail, and you don't want to use an alternate MTA.
Install ucspi.�This program handles incoming tcp connections. + Download ucspi and install it.
[root@yourserver root]# cd /usr/local/src +[root@yourserver src]# tar xzf /tmp/ucspi-tcp-0.88.tar.gz +[root@yourserver src]# cd ucspi-tcp-0.88 +[root@yourserver ucspi-tcp-0.88]# make ( cat warn-auto.sh; \ echo 'main="$1"; shift'; \ (many lines omitted) ./compile instcheck.c ./load instcheck hier.o auto_home.o unix.a byte.a -[root@yourserver ucspi-tcp-0.88]# make setup check +[root@yourserver ucspi-tcp-0.88]# make setup check ./install ./instcheck [root@yourserver ucspi-tcp-0.88]# -cd /usr/local/src +cd /usr/local/src tar xzf /tmp/ucspi-tcp-0.88.tar.gz cd ucspi-tcp-0.88 make -make setup check
Verify that ucspi-tcp was installed successfully by -running the tcpserver program which is part of ucspi-tcp:
[root@yourserver ucspi-tcp-0.88]# tcpserver +make setup checkVerify that ucspi-tcp was installed successfully by +running the tcpserver program which is part of ucspi-tcp:
[root@yourserver ucspi-tcp-0.88]# tcpserver tcpserver: usage: tcpserver [ -1UXpPhHrRoOdDqQv ] [ -c limit ] [ -x rules.cdb ] [ -B banner ] [ -g gid ] [ -u uid ] [ -b backlog ] [ -l localname ] [ -t timeout ] host port program [root@yourserver ucspi-tcp-0.88]# -(I'm not sure if this next step is 100% necessary, but when I skip it -I get problems. If you get the error 553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1) then you need to do this.) AOLServer sends outgoing mail via the ns_sendmail +I get problems. If you get the error 553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1) then you need to do this.) AOLServer sends outgoing mail via the ns_sendmail command, which pipes a command to the sendmail executable. Or, in our case, the qmail replacement wrapper for the sendmail executable. In some cases, though, the outgoing mail requset is apparently sent @@ -106,31 +106,31 @@ Unless this mail is addressed to the same machine, qmail thinks that it's an attempt to relay mail, and rejects it. So these two commands set up an exception so that any mail sent from 127.0.0.1 is allowed to -send outgoing mail.
[root@yourserver ucspi-tcp-0.88]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/tcp.smtp.txt /etc/tcp.smtp -[root@yourserver ucspi-tcp-0.88]# tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp -cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/tcp.smtp.txt /etc/tcp.smtp -tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtpDownload qmail, - set up the standard supporting users and build the binaries:
(If you are using Red Hat 9.0, you need to put #include <errno.h> as the first line of /usr/local/src/qmail-1.03/error.h. More information)
[root@yourserver root]# cd /usr/local/src -[root@yourserver src]# tar xzf /tmp/qmail-1.03.tar.gz -[root@yourserver src]# mkdir /var/qmail -[root@yourserver src]# groupadd nofiles -[root@yourserver src]# useradd -g nofiles -d /var/qmail/alias alias -[root@yourserver src]# useradd -g nofiles -d /var/qmail qmaild -[root@yourserver src]# useradd -g nofiles -d /var/qmail qmaill -[root@yourserver src]# useradd -g nofiles -d /var/qmail qmailp -[root@yourserver src]# groupadd qmail -[root@yourserver src]# useradd -g qmail -d /var/qmail qmailq -[root@yourserver src]# useradd -g qmail -d /var/qmail qmailr -[root@yourserver src]# useradd -g qmail -d /var/qmail qmails -[root@yourserver src]# cd qmail-1.03 -[root@yourserver qmail-1.03]# make setup check +send outgoing mail.[root@yourserver ucspi-tcp-0.88]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/tcp.smtp.txt /etc/tcp.smtp +[root@yourserver ucspi-tcp-0.88]# tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp +cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/tcp.smtp.txt /etc/tcp.smtp +tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
Download qmail, + set up the standard supporting users and build the binaries:
(If you are using Red Hat 9.0, you need to put #include <errno.h> as the first line of /usr/local/src/qmail-1.03/error.h. More information)
[root@yourserver root]# cd /usr/local/src +[root@yourserver src]# tar xzf /tmp/qmail-1.03.tar.gz +[root@yourserver src]# mkdir /var/qmail +[root@yourserver src]# groupadd nofiles +[root@yourserver src]# useradd -g nofiles -d /var/qmail/alias alias +[root@yourserver src]# useradd -g nofiles -d /var/qmail qmaild +[root@yourserver src]# useradd -g nofiles -d /var/qmail qmaill +[root@yourserver src]# useradd -g nofiles -d /var/qmail qmailp +[root@yourserver src]# groupadd qmail +[root@yourserver src]# useradd -g qmail -d /var/qmail qmailq +[root@yourserver src]# useradd -g qmail -d /var/qmail qmailr +[root@yourserver src]# useradd -g qmail -d /var/qmail qmails +[root@yourserver src]# cd qmail-1.03 +[root@yourserver qmail-1.03]# make setup check ( cat warn-auto.sh; \ echo CC=\'`head -1 conf-cc`\'; \ (many lines omitted) ./install ./instcheck [root@yourserver qmail-1.03]# -cd /usr/local/src +cd /usr/local/src tar xzf /tmp/qmail-1.03.tar.gz mkdir /var/qmail groupadd nofiles @@ -143,11 +143,11 @@ useradd -g qmail -d /var/qmail qmailr useradd -g qmail -d /var/qmail qmails cd qmail-1.03 -make setup check
Replace sendmail with qmail's wrapper.
[root@yourserver qmail-1.03]# rm -f /usr/bin/sendmail -[root@yourserver qmail-1.03]# ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail +make setup checkReplace sendmail with qmail's wrapper.
[root@yourserver qmail-1.03]# rm -f /usr/bin/sendmail +[root@yourserver qmail-1.03]# ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail [root@yourserver qmail-1.03]# -rm -f /usr/bin/sendmail -ln -s /var/qmail/bin/sendmail /usr/sbin/sendmailConfigure qmail - specifically, run the config script to set up files in /var/qmail/control specifying the computer's identity and which addresses it should accept mail for. This command will automatically set up qmail correctly if you have correctly set a valid host nome. If not, you'll want to read /var/qmail/doc/INSTALL.ctl to find out how to configure qmail.
[root@yourserver qmail-1.03]# ./config-fast yourserver.test +rm -f /usr/bin/sendmail +ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail
Configure qmail - specifically, run the config script to set up files in /var/qmail/control specifying the computer's identity and which addresses it should accept mail for. This command will automatically set up qmail correctly if you have correctly set a valid host nome. If not, you'll want to read /var/qmail/doc/INSTALL.ctl to find out how to configure qmail.
[root@yourserver qmail-1.03]# ./config-fast yourserver.test Your fully qualified host name is yourserver.test. Putting yourserver.test into control/me... Putting yourserver.test into control/defaultdomain... @@ -157,36 +157,36 @@ Now qmail will refuse to accept SMTP messages except to yourserver.test. Make sure to change rcpthosts if you add hosts to locals or virtualdomains! [root@yourserver qmail-1.03]# -./config-fast yourserver.test
All incoming mail that isn't for a specific user is handled by the alias user. This includes all root mail. These commands prepare the alias user to receive mail.
[root@yourserver qmail-1.03]# cd ~alias; touch .qmail-postmaster .qmail-mailer-daemon .qmail-root -[root@yourserver alias]# chmod 644 ~alias/.qmail* -[root@yourserver alias]# /var/qmail/bin/maildirmake ~alias/Maildir/ -[root@yourserver alias]# chown -R alias.nofiles /var/qmail/alias/Maildir +./config-fast yourserver.test
All incoming mail that isn't for a specific user is handled by the alias user. This includes all root mail. These commands prepare the alias user to receive mail.
[root@yourserver qmail-1.03]# cd ~alias; touch .qmail-postmaster .qmail-mailer-daemon .qmail-root +[root@yourserver alias]# chmod 644 ~alias/.qmail* +[root@yourserver alias]# /var/qmail/bin/maildirmake ~alias/Maildir/ +[root@yourserver alias]# chown -R alias.nofiles /var/qmail/alias/Maildir [root@yourserver alias]# -cd ~alias; touch .qmail-postmaster .qmail-mailer-daemon .qmail-root +cd ~alias; touch .qmail-postmaster .qmail-mailer-daemon .qmail-root chmod 644 ~alias/.qmail* /var/qmail/bin/maildirmake ~alias/Maildir/ -chown -R alias.nofiles /var/qmail/alias/Maildir
Configure qmail to use the Maildir delivery format - (instead of mbox), and install a version of the qmail startup script modified to use Maildir.
[root@yourserver alias]# echo "./Maildir" > /var/qmail/bin/.qmail -[root@yourserver alias]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/qmail.rc.txt /var/qmail/rc -[root@yourserver alias]# chmod 755 /var/qmail/rc +chown -R alias.nofiles /var/qmail/alias/MaildirConfigure qmail to use the Maildir delivery format + (instead of mbox), and install a version of the qmail startup script modified to use Maildir.
[root@yourserver alias]# echo "./Maildir" > /var/qmail/bin/.qmail +[root@yourserver alias]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/qmail.rc.txt /var/qmail/rc +[root@yourserver alias]# chmod 755 /var/qmail/rc [root@yourserver alias]# -echo "./Maildir" > /var/qmail/bin/.qmail +echo "./Maildir" > /var/qmail/bin/.qmail cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/qmail.rc.txt /var/qmail/rc chmod 755 /var/qmail/rc -
Set up the skeleton directory so that new users will - be configured for qmail.
[root@localhost root]# /var/qmail/bin/maildirmake /etc/skel/Maildir -[root@localhost root]# echo "./Maildir/" > /etc/skel/.qmail +Set up the skeleton directory so that new users will + be configured for qmail.
[root@localhost root]# /var/qmail/bin/maildirmake /etc/skel/Maildir +[root@localhost root]# echo "./Maildir/" > /etc/skel/.qmail [root@localhost root]# -/var/qmail/bin/maildirmake /etc/skel/Maildir -echo "./Maildir/" > /etc/skel/.qmailQmail runs in two parts. First, several different +
/var/qmail/bin/maildirmake /etc/skel/Maildir +echo "./Maildir/" > /etc/skel/.qmail
Qmail runs in two parts. First, several different qmail daemons are started by the qmail rc file. Second, a - process is started in within tcpserver to listen for incoming smtp traffic. Run both of these commands to start qmail. Be very careful about line breaks - there should be a total of two commands here. Note also that the tcpserver command takes the uid and guid of qmaild, which will only be 502 and 501 if you have followed all of these instructions exactly and in order. Otherwise, grep qmaild /etc/passwd to find uid and guid, in that order.
[root@yourserver alias]# /usr/local/bin/tcpserver -x /etc/tcp.smtp.cdb -v -u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd 2>&1 | /var/qmail/bin/splogger smtpd 3 & + process is started in within tcpserver to listen for incoming smtp traffic. Run both of these commands to start qmail. Be very careful about line breaks - there should be a total of two commands here. Note also that the tcpserver command takes the uid and guid of qmaild, which will only be 502 and 501 if you have followed all of these instructions exactly and in order. Otherwise, grep qmaild /etc/passwd to find uid and guid, in that order.[root@yourserver alias]# /usr/local/bin/tcpserver -x /etc/tcp.smtp.cdb -v -u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd 2>&1 | /var/qmail/bin/splogger smtpd 3 & [1] 15863 -[root@yourserver alias]# csh -cf '/var/qmail/rc &' +[root@yourserver alias]# csh -cf '/var/qmail/rc &' [1] 15865 [root@yourserver alias]# -/usr/local/bin/tcpserver -x /etc/tcp.smtp.cdb -v -u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd 2>&1 | /var/qmail/bin/splogger smtpd 3 & -csh -cf '/var/qmail/rc &'Verify that seven different qmail threads are running:
[root@yourserver alias]# ps -auxw | grep +/usr/local/bin/tcpserver -x /etc/tcp.smtp.cdb -v -u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd 2>&1 | /var/qmail/bin/splogger smtpd 3 & +csh -cf '/var/qmail/rc &'
Verify that seven different qmail threads are running:
[root@yourserver alias]# ps -auxw | grep qmail qmaild 4269 0.0 0.3 1384 452 pts/0 S 21:21 0:00 [tcpserver] root 4270 0.0 0.3 1340 412 pts/0 S 21:21 0:00 /var/qmail/bin/splogger smtpd 3 @@ -196,10 +196,10 @@ qmailr 4275 0.0 0.2 1328 272 pts/0 S 21:21 0:00 [qmail-rspawn] qmailq 4276 0.0 0.2 1324 280 pts/0 S 21:21 0:00 [qmail-clean] root 4278 0.0 0.5 3280 632 pts/0 S 21:21 0:00 grep qmail -[root@yourserver alias]#Further verify by sending and receiving email. Incoming mail for root is stored in /var/qmail/alias/Maildir. If it worked, make it permanent by putting the same commands in your startup scripts. (These instructions put the commands in rc.local, which means that they'll be run once, on boot. There will be no monitoring and no interface to start and stop and check status. We ought instead to either use full init scripts or daemontools.)
[root@yourserver alias]# echo "/usr/local/bin/tcpserver -x /etc/tcp.smtp.cdb -v -u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd \ " >> /etc/rc.local -[root@yourserver alias]# echo "2>&1 | /var/qmail/bin/splogger smtpd 3 & " >> /etc/rc.local -[root@yourserver alias]# echo "csh -cf '/var/qmail/rc &' " >> /etc/rc.local +[root@yourserver alias]#Further verify by sending and receiving email. Incoming mail for root is stored in /var/qmail/alias/Maildir. If it worked, make it permanent by putting the same commands in your startup scripts. (These instructions put the commands in rc.local, which means that they'll be run once, on boot. There will be no monitoring and no interface to start and stop and check status. We ought instead to either use full init scripts or daemontools.)
[root@yourserver alias]# echo "/usr/local/bin/tcpserver -x /etc/tcp.smtp.cdb -v -u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd \ " >> /etc/rc.local +[root@yourserver alias]# echo "2>&1 | /var/qmail/bin/splogger smtpd 3 & " >> /etc/rc.local +[root@yourserver alias]# echo "csh -cf '/var/qmail/rc &' " >> /etc/rc.local [root@yourserver alias]# -echo "/usr/local/bin/tcpserver -x /etc/tcp.smtp.cdb -v -u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd \ " >> /etc/rc.local +echo "/usr/local/bin/tcpserver -x /etc/tcp.smtp.cdb -v -u 502 -g 501 0 smtp /var/qmail/bin/qmail-smtpd \ " >> /etc/rc.local echo "2>&1 | /var/qmail/bin/splogger smtpd 3 & " >> /etc/rc.local -echo "csh -cf '/var/qmail/rc &' " >> /etc/rc.local
($Id$)View comments on this page at openacs.org +echo "csh -cf '/var/qmail/rc &' " >> /etc/rc.local($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/mac-install.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/Attic/mac-install.html,v diff -u -r1.3.2.2 -r1.3.2.3 --- openacs-4/packages/acs-core-docs/www/mac-install.html 29 Apr 2003 05:58:33 -0000 1.3.2.2 +++ openacs-4/packages/acs-core-docs/www/mac-install.html 7 May 2003 17:40:59 -0000 1.3.2.3 @@ -1,2 +1,2 @@ -Chapter�5.�Installing on a Macintosh Table of Contents
Prev Home Next OpenACS Installation Guide for Windows2000 Up OpenACS Installation Guide for Mac OS X
docs@openacs.orgView comments on this page at openacs.org +Chapter�5.�Installing on a Macintosh Table of Contents
Prev Home Next OpenACS Installation Guide for Windows2000 Up OpenACS Installation Guide for Mac OS X
docs@openacs.orgView comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/mac-installation.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/mac-installation.html,v diff -u -r1.4.2.3 -r1.4.2.4 --- openacs-4/packages/acs-core-docs/www/mac-installation.html 4 May 2003 06:30:02 -0000 1.4.2.3 +++ openacs-4/packages/acs-core-docs/www/mac-installation.html 7 May 2003 17:40:59 -0000 1.4.2.4 @@ -1,3 +1,3 @@ -OpenACS Installation Guide for Mac OS X There are several resources for installing on OS X.
An +
OpenACS Installation Guide for Mac OS X There are several resources for installing on OS X.
($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/maintenance-web.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/maintenance-web.html,v diff -u -r1.1.2.6 -r1.1.2.7 --- openacs-4/packages/acs-core-docs/www/maintenance-web.html 4 May 2003 06:30:02 -0000 1.1.2.6 +++ openacs-4/packages/acs-core-docs/www/maintenance-web.html 7 May 2003 17:40:59 -0000 1.1.2.7 @@ -1,10 +1,10 @@ -Hosting Web Sites +
Hosting Web Sites by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.This section collection of maintenance - tasks and alternate configurations for AOLserver. This section has not yet been updated for 4.6.3
This is an alternative method for keeping the AOLserver + tasks and alternate configurations for AOLserver. This section has not yet been updated for 4.6.3
This is an alternative method for keeping the AOLserver process running. The recommended method is to run AOLserver supervised.
This step should be completed as root. This can break every service @@ -13,32 +13,32 @@ There are 2 general steps to getting this working.
Install a script called - restart-aolserver. This + restart-aolserver. This script doesn't actually restart AOLserver - it just kills it.
Ask the OS to restart our service whenever it's not running. We do this by adding a line to - /etc/inittab. + /etc/inittab.
- Calling restart-aolserver + Calling restart-aolserver kills our service. The OS notices that our service is not running, so it automatically restarts it. Thus, calling - restart-aolserver effectively + restart-aolserver effectively restarts our service.
Copy this file into - /tmp/restart-aolserver.txt. + /tmp/restart-aolserver.txt.
This script needs to be SUID-root, which means that the script will run as root. This is necessary to ensure that the AOLserver processes are killed regardless of who owns them. However the script should be executable by the - web group to ensure that the + web group to ensure that the users updating the web page can use the script, but that general system users cannot run the script. You also need to have Perl installed and also a symbolic link to it in - /usr/local/bin. + /usr/local/bin.
joeuser:~$ su - Password: *********** @@ -47,10 +47,10 @@ root:~# chmod 4750 /usr/local/bin/restart-aolserver root:~# ln -s /usr/bin/perl /usr/local/bin/perl root:~# exit- Test the restart-aolserver + Test the restart-aolserver script. We'll first kill all running servers to clean the slate. Then, we'll start one server and use - restart-aolserver to kill + restart-aolserver to kill it. If it works, then there should be no more servers running. You should see the following lines.
joeuser:~$ killall nsd @@ -62,19 +62,19 @@ nsd: no process killedThe number 23727 indicates the process id(s) (PIDs) of the processes being killed. It is important that no processes are killed by the second - call to killall. If there are + call to killall. If there are processes being killed, it means that the script is not working.
- Assuming that the restart-aolserver + Assuming that the restart-aolserver script worked, login as root and open - /etc/inittab for + /etc/inittab for editing.
joeuser:~$ su - Password: ************ root:~# emacs -nw /etc/inittabCopy this line into the bottom of the file as a template, making sure that the first field - nss1 is unique. + nss1 is unique.
nss1:345:respawn:/usr/local/aolserver/bin/nsd-postgres -i -u nobody -g web -t /home/joeuser/web/birdnotes/nsd.tclImportant: Make sure there is a @@ -83,40 +83,40 @@ failures.
Still as root, enter the following command to re-initialize - /etc/inittab.
+ /etc/inittab.root:~# killall nsd nsd: no process killed root:~# /sbin/init qSee if it worked by running the - restart-aolserver script + restart-aolserver script again.
root:~# restart-aolserver birdnotes Killing 23750
If processes were killed, congratulations, your server is now automated for startup and shutdown. -
If you want your webserver to be http://yourserver.com, it must run on port 80, the default HTTP port. You set this in the config.tcl file. You will need to start the service as - root. If you follow the instructions +
If you want your webserver to be http://yourserver.com, it must run on port 80, the default HTTP port. You set this in the config.tcl file. You will need to start the service as + root. If you follow the instructions above for automating startup, this will be taken care of, but if you ever start the - server from the command line, be sure to su + server from the command line, be sure to su - first.
Port 80 is a privileged port. Only certain users - can claim it. When you start nsd as + can claim it. When you start nsd as root, it obtains the port, and then changes to run as whatever user you specify in the server configuration file. This ensures a high level of security, as the server, once started, is not running as - root. This mean that if someone was + root. This mean that if someone was able to exploit your web server to execute a command on your server, - they would not be able to gain root - access.
Services on different ports.�To run a different service on another port but the same + they would not be able to gain root + access.
Services on different ports.�To run a different service on another port but the same ip, simply repeat Install OpenACS 4.6.3 replacing - service0, and change the + service0, and change the
set httpport 8000 set httpsport 8443to different values.
Services on different host names.�For example, suppose you want to support -http://foo.com and - http://bar.com on the same +http://foo.com and + http://bar.com on the same machine. The easiest way is to assign each one a different ip address. Then you can install two services as above, but with different values for Index: openacs-4/packages/acs-core-docs/www/maintenance.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/Attic/maintenance.html,v diff -u -r1.1.2.5 -r1.1.2.6 --- openacs-4/packages/acs-core-docs/www/maintenance.html 29 Apr 2003 05:58:33 -0000 1.1.2.5 +++ openacs-4/packages/acs-core-docs/www/maintenance.html 7 May 2003 17:40:59 -0000 1.1.2.6 @@ -1,2 +1,2 @@ -
Chapter�7.�Maintenance Table of Contents
View comments on this page at openacs.org +Chapter�7.�Maintenance Table of Contents
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/object-identity.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/object-identity.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/object-identity.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/object-identity.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,5 +1,5 @@ -Object Identity +
Object Identity by Rafael H. Schloming
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. Index: openacs-4/packages/acs-core-docs/www/object-system-design.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/object-system-design.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/object-system-design.html 29 Apr 2003 05:58:33 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/object-system-design.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,18 +1,18 @@ -OpenACS 4 Object Model Design +
OpenACS 4 Object Model Design by Pete Su, Michael Yoon, Richard Li and Rafael Schloming
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Before OpenACS 4, software developers writing OpenACS applications or modules would develop each data model separately. However, many applications built on OpenACS share certain characteristics or require certain common services. Examples of such services include:
User comments
Storage of user-defined or extensible sets of attributes
Access control
General auditing and bookkeeping (e.g. creation date, IP addresses, and @@ -37,21 +37,21 @@ object type (e.g. users) to instances of another object type (e.g. groups).
The next section will explore these facilities in the context of the the -particular programming idioms that we wish to generalize.
Related Links
This design document should be read along with the design documents for the new groups system, subsites and the permissions system
The motivation for most of the facilities in the OpenACS 4 Object Model can be +particular programming idioms that we wish to generalize.
Related Links
This design document should be read along with the design documents for the new groups system, subsites and the permissions system
The motivation for most of the facilities in the OpenACS 4 Object Model can be understood in the context of the 3.x code base and the kinds of programming -idioms that evolved there. These are listed and discussed below.
Object identification is a central mechanism in OpenACS 4. Every application +idioms that evolved there. These are listed and discussed below.
Object identification is a central mechanism in OpenACS 4. Every application object in OpenACS 4 has a unique ID which is mapped to a row in a central table -called acs_objects. Developers that wish to use OpenACS 4 services +called acs_objects. Developers that wish to use OpenACS 4 services need only take a few simple steps to make sure that their application objects appear in this table. The fact that every object has a known unique identifier means that the core can deal with all objects in a generic way. In other words, we use object identifiers to enable centralized services in a global and uniform manner.
Implicit Object Identifiers in OpenACS 3.x
The motivation for implementing general object identifiers comes from several observations of data models in OpenACS 3.x. Many modules use a -(user_id, group_id, scope) column-triple for the purpose of +(user_id, group_id, scope) column-triple for the purpose of recording ownership information on objects, for access control. User/groups -also uses (user_id, group_id) pairs in its -user_group_map table as a way to identify data associated with a +also uses (user_id, group_id) pairs in its +user_group_map table as a way to identify data associated with a single membership relation.
Also, in OpenACS 3.x many utility modules exist that do nothing more than attach some extra attributes to existing application data. For example, general comments maintains a table that maps application "page" @@ -68,23 +68,23 @@ construction of generic application-independent services unnecessarily difficult.
Object Identifiers in OpenACS 4
The OpenACS 4 Object Model defines a single mechanism that applications use to attach unique identifiers to application data. This identifier is the primary -key of the acs_objects table. This table forms the core of what +key of the acs_objects table. This table forms the core of what we need to provide generic services like access control, general attribute storage, general presentation and forms tools, and generalized administrative interfaces. In addition, the object system provides an API that makes it easy to create new objects when creating application data. All an application must do to take advantage of general services in OpenACS 4 is to use the new API to make sure every object the system is to manage is associated with a row in -acs_objects. More importantly, if they do this, new services +acs_objects. More importantly, if they do this, new services like general comments can be created without requiring existing applications to "hook into" them via new metadata.
Note: Object identifiers are a good example of metadata -in the new system. Each row in acs_objects stores information +in the new system. Each row in acs_objects stores information about the application object, but not the application object itself. This becomes more clear if you skip ahead and look at the SQL schema code -that defines this table.
Until the implementation of the general permissions system, every OpenACS +that defines this table.
Until the implementation of the general permissions system, every OpenACS application had to manage access control to its data separately. Later on, a notion of "scoping" was introduced into the core data model.
"Scope" is a term best explained by example. Consider some -hypothetical rows in the address_book table:
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ... The first row represents an entry in User 123's personal address book, +hypothetical rows in the address_book table:
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ... The first row represents an entry in User 123's personal address book, the second row represents an entry in User Group 456's shared address book, and the third row represents an entry in the site's public address book.
In this way, the scoping columns identify the security context in which a @@ -98,29 +98,29 @@ bboard message would probably list a bboard topic as its context, and a bboard topic might list a subsite as its context. Thus, contexts make it easier to break the site up into security domains according to its natural -structure. An object's context is stored in the context_id -column of the acs_objects table.
We use an object's context to provide a default answer to questions +structure. An object's context is stored in the context_id +column of the acs_objects table.
We use an object's context to provide a default answer to questions regarding access control. Whenever we ask a question of the form "can user X perform action Y on object Z", the OpenACS security model will defer to an object's context if there is no information about user X's permission to perform action Y on object Z.
The context system forms the basis for the rest of the OpenACS access control system, which is described in in two separate documents: one for the permissions system and another for the party groups system. The context system -is also used to implement subsites.
As mentioned above, many OpenACS modules provide extensible data models, and +is also used to implement subsites.
As mentioned above, many OpenACS modules provide extensible data models, and need to use application specific mechanisms to keep track of user defined attributes and to map application data to these attributes. In the past, modules either used user/groups or their own ad hoc data model to provide this functionality.
User/Groups in OpenACS 3.x
The user/group system allowed developers to define group types along with attributes to be stored with each instance of a group type. Each group type could define a helper table that stored attributes on each instance of the group type. This table was called the -"_info" table because the name was generated by -appending _info to the name of the group type.
The user/groups data model also provided the -user_group_type_member_fields and -user_group_member_fields tables to define attributes for members +"_info" table because the name was generated by +appending _info to the name of the group type.
The user/groups data model also provided the +user_group_type_member_fields and +user_group_member_fields tables to define attributes for members of groups of a specific type and for members of a specific group, -respectively. The user_group_member_field_map table stored -values for both categories of attributes in its field_value +respectively. The user_group_member_field_map table stored +values for both categories of attributes in its field_value column. These tables allowed developers and users to define custom sets of attributes to store on groups and group members without changing the data model at the code level.
Many applications in OpenACS 3.x and earlier used the group type mechanism in @@ -138,36 +138,36 @@ information. This resulted in core data tables that were too "fat", containing a hodge podge of unrelated information that should have been normalized away. The canonical example of this is the explosion of the -users table in OpenACS 3.x. In addition to being sloppy technically, +users table in OpenACS 3.x. In addition to being sloppy technically, these fat tables have a couple of other problems:
They degrade performance.
Denormalization can make it hard to maintain consistency constraints on the data.
Object subtypes provide a way to factor the data model while still keeping track of the fact that each member of a subtype (i.e. for each row in the subtype's table), is also a member of the parent type (i.e. there is a corresponding row in the parent type table). Therefore, applications an use this mechanism without worrying about this bookkeeping themselves, and we avoid having applications pollute the core data model with their specific -information.
As we described above, the OpenACS 3.x user/groups system stored object +information.
As we described above, the OpenACS 3.x user/groups system stored object attributes in two ways. The first was to use columns in the helper table. The second consisted of two tables, one describing attributes and one storing values, to provide a flexible means for attaching attributes to metadata objects. This style of attribute storage is used in several other parts of OpenACS 3.x, and we will refer to it as "skinny tables". For -example:
In the Ecommerce data model, the ec_custom_product_fields +example:
In the Ecommerce data model, the ec_custom_product_fields table defines attributes for catalog products, and the -ec_custom_product_field_values table stores values for those -attributes.
In the Photo DB data model, the ph_custom_photo_fields table +ec_custom_product_field_values table stores values for those +attributes.
In the Photo DB data model, the ph_custom_photo_fields table defines attributes for the photographs owned by a specific user, and tables named according to the convention -"ph_user_<user_id>_custom_info" are used to +"ph_user_<user_id>_custom_info" are used to store values for those attributes.
In addition, there are some instances where we are not using this model -but should, e.g. the users_preferences table, which +but should, e.g. the users_preferences table, which stores preferences for registered users in columns such as -prefer_text_only_p and dont_spam_me_p. The +prefer_text_only_p and dont_spam_me_p. The "standard" way for an OpenACS 3.x-based application to add to the list -of user preferences is to add a column to the users_preferences +of user preferences is to add a column to the users_preferences table (exactly the kind of data model change that has historically complicated the process of upgrading to a more recent OpenACS version).
The Objet Model generalizes the scheme used in the old OpenACS 3.x user/groups -system. It defines a table called acs_attributes that record +system. It defines a table called acs_attributes that record what attributes belong to which object types, and how the attributes are stored. As before, attributes can either be stored in helper tables, or in a single central skinny table. The developer makes this choice on a case by @@ -177,19 +177,19 @@ skinny tables because doing so allows developers and users to dynamically update the set of attributes stored on an object without updating the data model at the code level. The bottom line: Helper tables are more functional -and more efficient, skinny tables are more flexible but limited.
Many OpenACS 3.x modules use mapping tables to model relationships +and more efficient, skinny tables are more flexible but limited.
Many OpenACS 3.x modules use mapping tables to model relationships between application objects. Again, the 3.x user/groups system provides the canonical example of this design style. In that system, there was a single -table called user_group_map that kept track of which users +table called user_group_map that kept track of which users belonged to what groups. In addition, as we discussed in the previous -section, the system used the user_group_member_fields and -user_group_member_fields_map tables to allow developers to +section, the system used the user_group_member_fields and +user_group_member_fields_map tables to allow developers to attach custom attributes to group members. In fact, these attributes were not really attached to the users, but to the fact that a user was a member of a particular group - a subtle but important distinction.
In OpenACS 4, relation types generalize this mechanism. Relation types allow developers to define general mappings from objects of a given type T, to other objects of a given type R. Each relation type is a subtype -of acs_object, extended with extra attributes that store +of acs_object, extended with extra attributes that store constraints on the relation, and the types of objects the relation actually maps. In turn, each instance of a relation type is an object that represents a single fact of the form "the object t of type T is related to the @@ -208,9 +208,9 @@ object system could use the meta data in the types table to do useful things in a generic way on all relation types. But this mechanism doesn't really exist yet.
Relation types are a somewhat abstract idea. To get a better feel for -them, you should just skip to the data model.
The OpenACS 4 Object Model is designed to generalize and unify the following +them, you should just skip to the data model.
The OpenACS 4 Object Model is designed to generalize and unify the following mechanisms that are repeatedly implemented in OpenACS-based systems to manage -generic and application specific metadata:
The presence of a framework for subtyping and inheritance always brings up +generic and application specific metadata:
The presence of a framework for subtyping and inheritance always brings up the question of why we don't just use an object database. The main reason is that all of the major object database vendors ship products that are effectively tied to some set of object oriented programming languages. Their @@ -234,7 +234,7 @@ practice. Finally, object databases are not as widely used as traditional relational systems. They have not been tested as extensively and their scalability to very large databases is not proven (though some will disagree -with this statement).
The conclusion: the best design is to add a limited notion of subtyping to +with this statement).
The conclusion: the best design is to add a limited notion of subtyping to our existing relational data model. By doing this, we retain all the power of the relational data model while gaining the object oriented features we need most.
In the context of OpenACS 4, this means using the object model to make our @@ -247,7 +247,7 @@ designed to support, for example, a huge type tree like the Java runtime libraries might define.
This last point cannot be over-stressed: the object model is not meant to be used for large scale application data storage. It is -meant to represent and store metadata, not application data.
Like most data models, the OpenACS Core data model has two levels:
The knowledge level (i.e. the metadata model)
The operational level (i.e. the concrete data model)
You can browse the data models themselves from here:
The knowledge level data model for OpenACS objects centers around three tables +and things like constraint names are not included.
The knowledge level data model for OpenACS objects centers around three tables that keep track of object types, attributes, and relation types. The first -table is acs_object_types, shown here in an abbreviated +table is acs_object_types, shown here in an abbreviated form:
-create table acs_object_types ( +create table acs_object_types ( object_type varchar(100) not null primary key, supertype references acs_object_types (object_type), abstract_p char(1) default 'f' not null @@ -278,22 +278,22 @@This table contains one row for every object type in the system. The key things to note about this table are:
For every type, we store metadata for how to display this type in certain -contexts (pretty_name and pretty_plural).
If the type is a subtype, then its parent type is stored in the column -supertype.
We support a notion of "abstract" types that contain no +contexts (pretty_name and pretty_plural).
If the type is a subtype, then its parent type is stored in the column +supertype.
We support a notion of "abstract" types that contain no instances (as of 9/2000 this is not actually used). These types exist only to be subtyped. An example might be a type representing "shapes" that contains common characteristics of all shapes, but which is only used to create subtypes that represent real, concrete shapes like circles, squares, and so on.
Every type defines a table in which one can find one row for every -instance of this type (table_name, id_column).
type_extension_table is for naming a table that stores extra -generic attributes.
The second table we use to describe types is acs_attributes. +instance of this type (table_name, id_column).
type_extension_table is for naming a table that stores extra +generic attributes.
The second table we use to describe types is acs_attributes. Each row in this table represents a single attribute on a specific object type (e.g. the "password" attribute of the "user" type). Again, here is an abbreviated version of what this table looks like. The actual table used in the implementation is somewhat different and is discussed in a separate document.
-create table acs_attributes ( +create table acs_attributes ( attribute_id integer not null primary key object_type not null references acs_object_types (object_type), attribute_name varchar(100) not null, @@ -312,22 +312,22 @@The following points are important about this table:
Every attribute has a unique identifier.
Every attribute is associated with an object type.
We store various things about each attribute for presentation -(pretty_name, sort_order).
The data_type column stores type information on this +(pretty_name, sort_order).
The data_type column stores type information on this attribute. This is not the SQL type of the attribute; it is just a human readable name for the type of data we think the attribute holds (e.g. "String", or "Money"). This might be used later to -generate a user interface.
The sort_order column stores information about how to sort +generate a user interface.
The sort_order column stores information about how to sort the attribute values.
Attributes can either be stored explicitly in a table ("type specific storage") or in a skinny table ("generic storage"). In most cases, an attribute maps directly to a column in the table identified -by the table_name of the corresponding object type, although, as +by the table_name of the corresponding object type, although, as mentioned above, we sometimes store attribute values as key-value pairs in a "skinny" table. However, when you ask the question "What are the attributes of this type of object?", you don't really care about how the values for each attribute are stored (in a column or as key-value -pairs); you expect to receive the complete list of all attributes.
The max_n_values and min_n_values columns +pairs); you expect to receive the complete list of all attributes.
The max_n_values and min_n_values columns encode information about the number of values an attribute may hold. -Attributes can be defined to hold 0 or more total values.
The static_p flag indicates whether this attribute value is +Attributes can be defined to hold 0 or more total values.
The static_p flag indicates whether this attribute value is shard by all instances of a type, as with static member fields in C++. Static attribute are like group level attributes in OpenACS 3.x.
The final part of the knowledge level model keeps track of relationship types. We said above that object relationships are used to generalize the 3.x @@ -338,9 +338,9 @@ to the user. This is a subtle but important distinction, because it allowed the 3.x system to store multiple sets of attributes on a given user, one set for each group membership relation in which they participated.
In OpenACS 4, this sort of data can be stored as a relationship type, in -acs_rel_types. The key parts of this table look like this:
+acs_rel_types. The key parts of this table look like this:-create table acs_rel_types ( +create table acs_rel_types ( rel_type varchar(100) not null references acs_object_types(object_type), object_type_one not null @@ -357,28 +357,28 @@Things to note about this table:
The main part of this table records the fact that the relation is between -instances of object_type_one and instances of -object_type_two. Therefore, each instance of this relation type -will be a pair of objects of the appropriate types.
The role columns store human readable names for the roles +instances of object_type_one and instances of +object_type_two. Therefore, each instance of this relation type +will be a pair of objects of the appropriate types.
The role columns store human readable names for the roles played by each object in the relation (e.g. "employee" and "employer"). Each role must appear in the -acs_rel_roles.
The min_n_rels_one column, and its three friends allow the +acs_rel_roles.
The min_n_rels_one column, and its three friends allow the programmer to specify constraints on how many objects any given object can be -related to on either side of the relation.
This table is easier to understand if you also know how the acs_rels table works.
To summarize, the acs_object_types and -acs_attributes tables store metadata that describes every object +related to on either side of the relation.
This table is easier to understand if you also know how the acs_rels table works.
To summarize, the acs_object_types and +acs_attributes tables store metadata that describes every object type and attribute in the system. These tables generalize the group types -data model in OpenACS 3.x. The acs_rel_types table stores +data model in OpenACS 3.x. The acs_rel_types table stores information about relation types.
This part of the data model is somewhat analogous to the data dictionary in Oracle. The information stored here is primarily metadata that describes the data stored in the operational level of the data -model, which is discussed next.
The operational level data model centers around the -acs_objects table. This table contains a single row for every -instance of the type acs_object. The table contains the +model, which is discussed next.
The operational level data model centers around the +acs_objects table. This table contains a single row for every +instance of the type acs_object. The table contains the object's unique identifier, a reference to its type, security information, and generic auditing information. Here is what the table looks like:
-create table acs_objects ( +create table acs_objects ( object_id integer not null, object_type not null references acs_object_types (object_type), @@ -396,15 +396,15 @@As we said in Section III, security contexts are hierarchical and also modeled as objects. There is another table called -acs_object_context_index that stores the context hierarchy.
Other tables in the core data model store additional information related -to objects. The table acs_attribute_values and -acs_static_attr_values are used to store attribute values that +acs_object_context_index that stores the context hierarchy.
Other tables in the core data model store additional information related +to objects. The table acs_attribute_values and +acs_static_attr_values are used to store attribute values that are not stored in a helper table associated with the object's type. The former is used for instance attributes while the latter is used for class-wide "static" values. These tables have the same basic form, so we'll only show the first:
-create table acs_attribute_values ( +create table acs_attribute_values ( object_id not null references acs_objects (object_id) on delete cascade, attribute_id not null @@ -414,10 +414,10 @@ ); -Finally, the table acs_rels is used to store object pairs +
Finally, the table acs_rels is used to store object pairs that are instances of a relation type.
-create table acs_rels ( +create table acs_rels ( rel_id not null references acs_objects (object_id) primary key @@ -431,31 +431,31 @@ ); -This table is somewhat subtle:
rel_id is the ID of an instance of some relation +
This table is somewhat subtle:
rel_id is the ID of an instance of some relation type. We do this so we can store all the mapping tables in this one -table.
rel_type is the ID of the relation type to which this object +table.
rel_type is the ID of the relation type to which this object belongs.
The next two object IDs are the IDs of the objects being mapped.
All this table does is store one row for every pair of objects that we'd like to attach with a relation. Any additional attributes that we'd like to attach to this pair of objects is specified in the attributes of the relation type, and could be stored in any number of places. As in the 3.x user/groups system, these places include helper tables or -generic skinny tables.
This table, along with acs_attributes and -acs_attribute_values generalize the old user/group tables -user_group_map, user_group_member_fields_map and -user_group_member_fields.
The core tables in the OpenACS 4 data model store information about instances -of object types and relation types. The acs_object table +generic skinny tables.
This table, along with acs_attributes and +acs_attribute_values generalize the old user/group tables +user_group_map, user_group_member_fields_map and +user_group_member_fields.
The core tables in the OpenACS 4 data model store information about instances +of object types and relation types. The acs_object table provides the central location that contains a single row for every object in the system. Services can use this table along with the metadata in stored in the knowledge level data model to create, manage, query and manipulate -objects in a uniform manner. The acs_rels table has an analogous +objects in a uniform manner. The acs_rels table has an analogous role in storing information on relations.
These are all the tables that we'll discuss in this document. The rest of the Kernel data model is described in the documents for subsites, the permissions system and for the groups system.
Some examples of how these tables are used in the system can be found in -the discussion of the API, which comes next.
Now we'll examine each piece of the API in detail. Bear in mind that -the Object Model API is defined primarily through PL/SQL packages.
The object system provides an API for creating new object types and then -attaching attributes to them. The procedures create_type and -drop_type are used to create and delete type definitions.
The two calls show up in the package acs_object_type.
+the discussion of the API, which comes next.Now we'll examine each piece of the API in detail. Bear in mind that +the Object Model API is defined primarily through PL/SQL packages.
The object system provides an API for creating new object types and then +attaching attributes to them. The procedures create_type and +drop_type are used to create and delete type definitions.
The two calls show up in the package acs_object_type.
- procedure create_type ( + procedure create_type ( object_type in acs_object_types.object_type%TYPE, pretty_name in acs_object_types.pretty_name%TYPE, pretty_plural in acs_object_types.pretty_plural%TYPE, @@ -476,11 +476,11 @@ ); -Here the cascade_p argument indicates whether dropping a type +
Here the cascade_p argument indicates whether dropping a type should also remove all its subtypes from the system.
We define a similar interface for defining attributes in the package -acs_attribute:
+acs_attribute:- function create_attribute ( + function create_attribute ( object_type in acs_attributes.object_type%TYPE, attribute_name in acs_attributes.attribute_name%TYPE, datatype in acs_attributes.datatype%TYPE, @@ -506,7 +506,7 @@In addition, the following two calls are available for attaching extra annotations onto attributes:
- procedure add_description ( + procedure add_description ( object_type in acs_attribute_descriptions.object_type%TYPE, attribute_name in acs_attribute_descriptions.attribute_name%TYPE, description_key in acs_attribute_descriptions.description_key%TYPE, @@ -521,17 +521,17 @@At this point, what you must do to hook into the object system from your -own data model becomes clear:
Create a table that will store the instances of the new type.
Call acs_object_type.create_type() to fill in the metadata +own data model becomes clear:
Create a table that will store the instances of the new type.
Call acs_object_type.create_type() to fill in the metadata table on this new type. If you want your objects to appear in the -acs_objects table, then your new type must be a subtype of -acs_object.
Call acs_attribute.create_attribute() to fill in information +acs_objects table, then your new type must be a subtype of +acs_object.
Call acs_attribute.create_attribute() to fill in information on the attributes that this type defines.
So, suppose we are writing a new version of the ticket tracker for 4.0. We probably define a table to store tickets in, and each ticket might have an ID and a description. If we want each ticket to be an object, then -ticket_id must reference the object_id column in -acs_objects:
+ticket_id must reference the object_id column in +acs_objects:-create table tickets ( +create table tickets ( ticket_id references acs_objects (object_id), description varchar(512), ... @@ -541,7 +541,7 @@In addition to defining the table, we need this extra PL/SQL code to hook into the object type tables:
-declare +declare attr_id acs_attributes.attribute_id%TYPE; begin acs_object_type.create_type ( @@ -572,19 +572,19 @@ automatically be hooked into every generic object service that exists. Better still, this code need not be changed as new services are added. As an aside, the most important service that requires you to subtype -acs_object is permissions.The next important piece of the API is defined in the -acs_object package, and is concerned with creating and managing +acs_object is permissions.
The next important piece of the API is defined in the +acs_object package, and is concerned with creating and managing objects. This part of the API is designed to take care of the mundane bookkeeping needed to create objects and query their attributes. Realistically however, limitations in PL/SQL and Oracle will make it hard to build generic procedures for doing large scale queries in the object system, so developers who need to do this will probably have to be fairly familiar -with the data model at a lower level.
The function acs_object.new() makes a new object for you. The -function acs_object.delete() deletes an object. As before, this +with the data model at a lower level.
The function acs_object.new() makes a new object for you. The +function acs_object.delete() deletes an object. As before, this is an abbreviated interface with all the long type specs removed. See the data model or developer's guide for the full interface.
- function new ( + function new ( object_id in acs_objects.object_id%TYPE default null, object_type in acs_objects.object_type%TYPE default 'acs_object', @@ -604,10 +604,10 @@Next, we define some generic functions to manipulate attributes. Again, these interfaces are useful to an extent, but for large scale queries, it's likely that developers would have to query the data model directly, -and then encapsulate their queries in procedures.
For names, the default_name function is used if you don't +and then encapsulate their queries in procedures.
For names, the default_name function is used if you don't want to define your own name function.
- function name ( + function name ( object_id in acs_objects.object_id%TYPE ) return varchar; @@ -620,7 +620,7 @@The following functions tell you where attributes are stored, and fetch single attributes for you.
- procedure get_attribute_storage ( + procedure get_attribute_storage ( object_id_in in acs_objects.object_id%TYPE, attribute_name_in in acs_attributes.attribute_name%TYPE, v_column out varchar2, @@ -640,15 +640,15 @@ ); -The main use of the acs_object package is to create +
The main use of the acs_object package is to create application objects and make them available for services via the -acs_objects table. To do this, you just have to make sure you -call acs_object.new() on objects that you wish to appear in the -acs_objects table. In addition, all such objects must be -instances of some subtype of acs_object.
Continuing the ticket example, we might define the following sort of +acs_objects table. To do this, you just have to make sure you +call acs_object.new() on objects that you wish to appear in the +acs_objects table. In addition, all such objects must be +instances of some subtype of acs_object.
Continuing the ticket example, we might define the following sort of procedure for creating a new ticket:
- function new_ticket ( + function new_ticket ( package_id in tickets.ticket_id%TYPE default null, description in tickets.description%TYPE default '', @@ -675,23 +675,23 @@ application need only do three things:
Define a data model to describe application objects. This can just be a normal SQL table.
Create an object type, using code like in the example from the previous section.
Make sure application objects are created using -acs_object.new() in addition to whatever SQL code is needed to +acs_object.new() in addition to whatever SQL code is needed to insert a new row into the application data model.
One of the design goals of OpenACS 4 was to provide a straightforward and consistent mechanism to provide applications with general services. What we have seen here is that three simple steps and minimal changes in the application data model are sufficient to make sure that application objects -are represented in the acs_objects table. Subsequently, all of +are represented in the acs_objects table. Subsequently, all of the general services in OpenACS 4 (i.e. permissions, general comments, and so on) -are written to work with any object that appears in acs_objects. +are written to work with any object that appears in acs_objects. Therefore, in general these three steps are sufficient to make OpenACS 4 services -available to your application.
The relations system defines two packages: acs_rel_type for -creating and managing relation types, and acs_rel for relating +available to your application.
The relations system defines two packages: acs_rel_type for +creating and managing relation types, and acs_rel for relating objects.
These two procedures just insert and remove roles from the -acs_rel_roles table. This table stores the legal relationship +acs_rel_roles table. This table stores the legal relationship "roles" that can be used when creating relation types. Examples of roles are, say, "member", or "employer".
- procedure create_role ( + procedure create_role ( role in acs_rel_roles.role%TYPE ); @@ -700,10 +700,10 @@ ); -The main functions in the acs_rel_type package are used to +
The main functions in the acs_rel_type package are used to create and drop relation types.
- procedure create_type ( + procedure create_type ( rel_type in acs_rel_types.rel_type%TYPE, pretty_name in acs_object_types.pretty_name%TYPE, pretty_plural in acs_object_types.pretty_plural%TYPE, @@ -731,10 +731,10 @@ ); -Finally, the acs_rel package provides an API that you use to +
Finally, the acs_rel package provides an API that you use to create and destroy instances of a relation type:
- function new ( + function new ( rel_id in acs_rels.rel_id%TYPE default null, rel_type in acs_rels.rel_type%TYPE default 'relationship', object_id_one in acs_rels.object_id_one%TYPE, @@ -755,7 +755,7 @@ explicitly creating a table. First, we create a helper table to store state on each membership fact:-create table membership_rels ( +create table membership_rels ( rel_id constraint membership_rel_rel_id_fk references acs_rels (rel_id) constraint membership_rel_rel_id_pk @@ -769,7 +769,7 @@Then, we create a new object type to describe groups.
- acs_object_type.create_type ( + acs_object_type.create_type ( object_type => 'group', pretty_name => 'Group', pretty_plural => 'Groups', @@ -781,15 +781,15 @@In this example, we've made groups a subtype of -acs_object to make the code simpler. The actual data model is +acs_object to make the code simpler. The actual data model is somewhat different. Also, we've assumed that there is a helper table -called groups to store information on groups, and that there is -a helper table called group_types that has been defined to store -extra attributes on groups.
Now, assuming we have another object type called person to +called groups to store information on groups, and that there is +a helper table called group_types that has been defined to store +extra attributes on groups.
Now, assuming we have another object type called person to represent objects that can be group members, we define the following relationship type for group membership:
- acs_rel_type.create_role ('member'); + acs_rel_type.create_role ('member'); acs_rel_type.create_type ( rel_type => 'membership_rel', @@ -808,10 +808,10 @@ All this function does is create a new instance of the membership relation type and then insert the membership state into the helper table that we define above. In the actual implementation, this function is implemented in -the membership_rel package. Here we just define an independent +the membership_rel package. Here we just define an independent function:-function member_add ( +function member_add ( rel_id in membership_rels.rel_id%TYPE default null, rel_type in acs_rels.rel_type%TYPE default 'membership_rel', group in acs_rels.object_id_one%TYPE, @@ -843,7 +843,7 @@Another simple function can be defined to remove a member from a group:
- procedure member_delete ( + procedure member_delete ( rel_id in membership_rels.rel_id%TYPE ) is @@ -855,11 +855,11 @@ end; -The Object Model's API and data model provides a small set of simple procedures that allow applications to create object types, object instances, and object relations. Most of the data model is straightforward; the relation type mechanism is a bit more complex, but in return it provides functionality -on par with the old user/groups system in a more general way.
Pete Su generated this document +on par with the old user/groups system in a more general way.
Pete Su generated this document from material culled from other documents by Michael Yoon, Richard Li and Rafael Schloming. But, any remaining lies -are his and his alone.
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 9/09/2000 Pete Su 0.2 Edited for ACS 4 Beta 9/30/2000 Kai Wu 0.3 Edited for ACS 4.0.1, fixed some mistakes, removed use of term +are his and his alone.
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 9/09/2000 Pete Su 0.2 Edited for ACS 4 Beta 9/30/2000 Kai Wu 0.3 Edited for ACS 4.0.1, fixed some mistakes, removed use of term "OM" 11/07/2000 Pete Su
Prev Home Next OpenACS 4 Object Model Requirements Up OpenACS 4 Permissions Requirements
docs@openacs.orgView comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/object-system-requirements.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/object-system-requirements.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/object-system-requirements.html 29 Apr 2003 05:58:33 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/object-system-requirements.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,9 +1,9 @@ -OpenACS 4 Object Model Requirements +
OpenACS 4 Object Model Requirements By Pete Su
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -A major goal in OpenACS 4 is to unify and normalize many of the core services of the system into a coherent common data model and API. In the past, these services were provided to applications in an ad-hoc and irregular fashion. Examples of such services include:
General Comments
User/groups
Attribute storage in user/groups
General Permissions
Site wide search
General Auditing
All of these services involve relating extra information and services to @@ -22,15 +22,15 @@ of the application's data model - in order to enable certain generic services. The term "object" refers to any entity being represented within the OpenACS, and typically corresponds to a single row within the -relational database.
The OpenACS 4 Object Model must address five high-level requirements that +relational database.
The OpenACS 4 Object Model must address five high-level requirements that repeatedly exhibit themselves in the context of existing services in OpenACS 3.x, as described below.
Object Identifiers for General Services
Generic services require a single unambiguous way of identifying application objects that they manage or manipulate. In OpenACS 3.x, there are several different idioms that construct object identifiers from other data. -Many modules use a (user_id, group_id, scope) triple combination +Many modules use a (user_id, group_id, scope) triple combination for the purpose of recording ownership information on objects for access -control. User/groups also uses (user_id, group_id) pairs in its -user_group_map table as a way to identify data associated with a +control. User/groups also uses (user_id, group_id) pairs in its +user_group_map table as a way to identify data associated with a single membership relation.
Also in OpenACS 3.x, many utility modules exist that do nothing more than attach some extra attributes to existing application data. For example, general comments maintains a mapping table that maps application @@ -51,7 +51,7 @@ OpenACS application had to manage access control to its data separately. Later on, a notion of "scoping" was introduced into the core data model.
"Scope" is a term best explained by example. Consider some -hypothetical rows in the address_book table:
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ... The first row represents an entry in User 123's personal address book, +hypothetical rows in the address_book table:
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ... The first row represents an entry in User 123's personal address book, the second row represents an entry in User Group 456's shared address book, and the third row represents an entry in the site's public address book.
In this way, the scoping columns identify the security context in which a @@ -67,7 +67,7 @@ with a single piece of data, instead of the old composite keys described above.
Extensible Data Models
Another problem with previous OpenACS data models is that many of the central tables in the system became bloated as they were extended to support an -increasing number of modules. The users table is the best case +increasing number of modules. The users table is the best case in point: it became full of columns that exist for various special applications (e.g. user portraits), but that aren't really related to each other in any way except that they store information on users, i.e. the @@ -93,23 +93,23 @@ extensions, since such changes are difficult or dangerous to make at runtime, and can make updating the system difficult. Some example applications in OpenACS 3.x with modifiable data models include:
User/groups: developers and users can attach custom data to group types, -groups, and members of groups.
In the Ecommerce data model, the ec_custom_product_fields +groups, and members of groups.
In the Ecommerce data model, the ec_custom_product_fields table defines attributes for catalog products, and the -ec_custom_product_field_values table stores values for those -attributes.
In the PhotoDB data model, the ph_custom_photo_fields table +ec_custom_product_field_values table stores values for those +attributes.
In the PhotoDB data model, the ph_custom_photo_fields table defines attributes for the photographs owned by a specific user, and tables named according to the convention -"ph_user_<user_id>_custom_info" are used to +"ph_user_<user_id>_custom_info" are used to store values for those attributes.
Thus the Object Model must provide a general mechanism for applications and developers to modify or extend data models, without requiring changes to the SQL schema of the system. This ensures that all applications use the same base schema, resulting in a uniform and more maintainable system.
Generic Relations
Many OpenACS applications define simple relationships between application objects, and tag those relationships with extra data. In OpenACS 3.x, this was done using mapping tables. The user/groups module has the most highly developed data model for this purpose, using a single table called -user_group_map that mapped users to groups. In addition, it uses -the the user_group_member_fields and -user_group_member_fields_map tables to allow developers to +user_group_map that mapped users to groups. In addition, it uses +the the user_group_member_fields and +user_group_member_fields_map tables to allow developers to attach custom attributes to group members. In fact, these custom attributes were not really attached to the users, but to the fact that a user was a member of a particular group - a subtle but important distinction. As a @@ -121,13 +121,13 @@ Relation types are themselves object types that do nothing but represent relations. They can be used by applications that previously used user/groups for the same purpose, but without the extraneous, artificial -dependencies.
The Object Model package is a combination of data model and a procedural +dependencies.
The Object Model package is a combination of data model and a procedural API for manipulating application objects within an OpenACS instance. The OM allows developers to describe a hierarchical system of object types that store metadata on application objects. The object type system supports subtyping with inheritance, so new object types can be defined in terms of existing object types.
The OM data model forms the main part of the OpenACS 4 Kernel data model. The -other parts of the Kernel data model include:
Parties and Groups
Permissions
Each of these is documented elsewhere at length.
The data model for the object system provides support for the following +other parts of the Kernel data model include:
Parties and Groups
Permissions
Each of these is documented elsewhere at length.
The data model for the object system provides support for the following kinds of schema patterns that are used by many existing OpenACS modules:
- 10.0 Object Identification and Storage
Object identification is a central mechanism in the new metadata system. The fact that every object has a known unique identifier means that the core can deal with all objects in a generic way. Thus the only action required of @@ -217,7 +217,7 @@ 8/24/2000).
- 55.0 Object Relations
The data model should include a notion of pair-wise relations between objects. Relations should be able to record simple facts of the form "object X is related to object Y by relationship R," and also be -able to attach attributes to these facts.
The API should let programmers accomplish the following actions:
- 60.0 Object Type Creation
60.10 Create a New Object Type
The object system API should provide a procedure call that creates a new +able to attach attributes to these facts.
The API should let programmers accomplish the following actions:
- 60.0 Object Type Creation
60.10 Create a New Object Type
The object system API should provide a procedure call that creates a new object type by running the appropriate transactions on the object system data model. This API call is subject to the constraints laid out in the data model. We call this operation "instantiating" an object.
60.20 Create a New Object Subtype
The object system API should provide a procedure call for creating @@ -262,7 +262,7 @@ application's data model. In other words, it should be easy to "hook into" the object model, and that ability should not have a major impact on the application data model.
Note: Is the API the only way to obtain values? How does -this integrate with application level SQL queries?
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 08/10/2000 Bryan Quinn 0.2 Major re-write 08/11/2000 Pete Su 0.3 Draft completed after initial reviews 08/22/2000 Pete Su 0.4 Edited, updated to conform to requirements template, pending freeze 08/23/2000 Kai Wu � Final edits before freeze 08/24/2000 Pete Su 0.5 Edited for consistency 08/27/2000 Kai Wu 0.6 Put Object ID stuff first, because it makes more sense 08/28/2000 Pete Su 0.7 Added requirement that knowledge-level objects must be moveable between +this integrate with application level SQL queries?
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 08/10/2000 Bryan Quinn 0.2 Major re-write 08/11/2000 Pete Su 0.3 Draft completed after initial reviews 08/22/2000 Pete Su 0.4 Edited, updated to conform to requirements template, pending freeze 08/23/2000 Kai Wu � Final edits before freeze 08/24/2000 Pete Su 0.5 Edited for consistency 08/27/2000 Kai Wu 0.6 Put Object ID stuff first, because it makes more sense 08/28/2000 Pete Su 0.7 Added requirement that knowledge-level objects must be moveable between databases. 08/29/2000 Richard Li 0.8 Rewrote intro to match language and concepts in the design document. Also cleaned up usage a bit in the requirements section. Added short vague requirements on relation types. 09/06/2000 Pete Su 0.9 Edited for ACS 4 Beta release. 09/30/2000 Kai Wu View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/objects.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/objects.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/objects.html 4 May 2003 06:30:02 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/objects.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,10 +1,10 @@ -OpenACS 4.6.3 Data Models and the Object System +
OpenACS 4.6.3 Data Models and the Object System By Pete Su
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Developing data models in OpenACS 4.6.3 is much like developing data models for OpenACS 3, save for the implementation. As usual, you need to examine how to model the information that the application must store and @@ -35,7 +35,7 @@ represented in the application's data model that will need to be managed by any central service in OpenACS 4.6.3, or that may be reusable in the context of future applications. Every object in the system is -represented using a row in the acs_objects table. This +represented using a row in the acs_objects table. This table defines all the standard attributes that are stored on every object, including its system-wide unique ID, object type, and some generic auditing columns. @@ -47,19 +47,19 @@
The Permissions System lets you track who is allowed to do what to the rows in an application table, and gives you an easy way to enforce - this from Tcl.
Every object has an attribute called context_id + this from Tcl.
Every object has an attribute called context_id that provides a way to trivially specify both the default permissions for an object, and the intended "scope" of an - object. Just set the context_id to the controlling + object. Just set the context_id to the controlling object and forget about it.
And most importantly, any future object-level service - from a general-comments replacement to personalized ranking - will become available to your application "for free."
-
Using ACS objects is straightforward: all that's required are a few extra steps in the design of your application data model.
In order to hook our Notes application into the object system, we -make some calls to use our notes table as the basis for a +make some calls to use our notes table as the basis for a new object type. Object types are analogous to classes in programming languages such as C++ and Java. In Java, a class defines a set of attributes that store data and a set of methods @@ -68,21 +68,21 @@ define the programming interface to the data model.
The object type itself is described using data in the -acs_object_types and -acs_attributes tables, which play a role +acs_object_types and +acs_attributes tables, which play a role similar to the data dictionary in Oracle. As in Java, object types can inherit attributes from a parent type, so the type system forms a hierarchy. Unlike Java, Oracle does not support this inheritance transparently, so we have to make sure we add our own bookkeeping code to keep everything consistent. Below you'll find the code needed to describe a -new object type called notes in your +new object type called notes in your system.
Fire up your text editor and open the -ROOT/packages/notes/sql/oracle/notes-create.sql (ROOT/packages/notes/sql/postgresql/notes-create.sql for the PG version) file created +ROOT/packages/notes/sql/oracle/notes-create.sql (ROOT/packages/notes/sql/postgresql/notes-create.sql for the PG version) file created when we created the package. Then, do the following: -
-First, add an entry to the acs_object_types table with the following PL/SQL call: +
+First, add an entry to the acs_object_types table with the following PL/SQL call:
begin acs_object_type.create_type ( @@ -98,18 +98,18 @@ show errors;This PL/SQL call tells the system that we would like to use the table -NOTES as the basis for a new object type called -note. This type is a subtype of the -acs_object type, which means that we want to inherit all +NOTES as the basis for a new object type called +note. This type is a subtype of the +acs_object type, which means that we want to inherit all of the basic attributes of all ACS objects. As mentioned, it will take some work on our part to make this happen, since Oracle can't do it automatically. In general, most basic applications will define types -that are simple subtypes of acs_object. +that are simple subtypes of acs_object.
-Add entries to the acs_attributes table to describe +Add entries to the acs_attributes table to describe the data attributes of the new type. This data can eventually be used to do things like automatically generate user interfaces to manipulate -the notes table, though that functionality isn't yet +the notes table, though that functionality isn't yet available.
declare @@ -135,17 +135,17 @@ show errors;We can stop here and not bother to register the usual OpenACS 3.x -attributes of creation_user, creation_date -and last_modified, since the object type -acs_object already defines these attributes. Again, -because the new type note is a subtype of -acs_object, it will inherit these attributes, so there is +attributes of creation_user, creation_date +and last_modified, since the object type +acs_object already defines these attributes. Again, +because the new type note is a subtype of +acs_object, it will inherit these attributes, so there is no need for us to define them. -
The next thing we do is make a small modification to the data model to -reflect the fact that each row in the notes table +reflect the fact that each row in the notes table represents something that is not only an object of type -note, but also an acs_object. The new table +note, but also an acs_object. The new table definition looks like this:
create table notes ( @@ -155,18 +155,18 @@ body varchar(1024) )-The usual creation_date and -modified_date columns are absent since they already exist -in acs_objects. Also, note the constraint we have added -to reference the acs_objects table, which makes clear -that since note is a subtype of acs_object, +The usual creation_date and +modified_date columns are absent since they already exist +in acs_objects. Also, note the constraint we have added +to reference the acs_objects table, which makes clear +that since note is a subtype of acs_object, every row in the notes table must have a corresponding row in the -acs_objects table. This is the fundamental means by which +acs_objects table. This is the fundamental means by which we model inheritance; it guarantees that any services that -use the acs_objects table to find objects will +use the acs_objects table to find objects will transparently find any objects that are instances of any subtype of -acs_objects. -
The next step is to define a PL/SQL package for your new type, and write some basic procedures to create and delete objects. Here is a package definition for our new type: @@ -198,14 +198,14 @@ calls, since we haven't mentioned them before. These parameters are needed to fill out information that will be stored about the object that's not stored directly in the table you defined. The OpenACS 4.6.3 Object -System defines these attributes on the type acs_object +System defines these attributes on the type acs_object since all objects should have these attributes. Internally, there are tables that store this information for you. Most of the data is pretty self-explanatory and reflects attributes that existed in the earlier -OpenACS 3.x data models, with the exception of the context_id +OpenACS 3.x data models, with the exception of the context_id attribute.
-The context_id attribute stores the ID of an object that +The context_id attribute stores the ID of an object that represents the default security domain to which the object belongs. It is used by the permissions system in this way: if no permissions are explicitly attached to the object, @@ -214,14 +214,14 @@ object OBJ was "read only", then any other object that used OBJ as its context would also be "read only" by default. We'll talk about this more later. -
The PL/SQL package body contains the implementations of the procedures defined above. The only subtle thing going on here is that we must use -acs_object.new to insert a row into -acs_objects, before inserting a row into the -notes. Similarly, when we delete a row from -note, we have to be sure to delete the corresponding -acs_object row. +acs_object.new to insert a row into +acs_objects, before inserting a row into the +notes. Similarly, when we delete a row from +note, we have to be sure to delete the corresponding +acs_object row.
create or replace package body note as @@ -274,14 +274,14 @@ / show errors;-That's pretty much it! As long as you use the note.new -function to create notes, and the note.delete function to +That's pretty much it! As long as you use the note.new +function to create notes, and the note.delete function to delete them, you'll be assured that the relationship each -note has with its corresponding acs_object +note has with its corresponding acs_object is preserved.
The last thing to do is to make a file -ROOT/packages/notes/sql/notes-drop.sql so it's easy to +ROOT/packages/notes/sql/notes-drop.sql so it's easy to drop the data model when, say, you're testing:
begin @@ -292,17 +292,17 @@ drop package note; drop table notes; -While it is hard to give general design advice without knowing anything about a particular application, you should follow the following rule of thumb when deciding when to hook part of your data model to the object system:
Anything in your data model that needs to be available to general OpenACS services such as user comments, permissions, and so on should be a -subtype of acs_object. In addition, if you want your data +subtype of acs_object. In addition, if you want your data model to take advantage of attributes that exist in some object type -that is a subtype of acs_object, then you should use the +that is a subtype of acs_object, then you should use the object system.
For example, for most applications, you will want to use objects to @@ -312,7 +312,7 @@ kind of design decision is mostly made on an application-by-application basis, but this is a good baseline from which to start. -
In this section we cover some overall guidelines for designing data models that are meant to be integrated with the OpenACS object system. @@ -322,21 +322,21 @@
-Never utilize fields in the acs_objects table in +Never utilize fields in the acs_objects table in application specific ways. That is, never assign any application-specific semantics to this data. In the notes -application, we use the creation_date and -last_modified fields, but this is OK since we do not +application, we use the creation_date and +last_modified fields, but this is OK since we do not assign any application-specific meaning to these fields.
In particular, never assign any application specific semantics to the -context_id attribute of an object. This field is used for +context_id attribute of an object. This field is used for a very specific purpose by the permissions system, and using this field in any other way whatsoever is guaranteed to make your application act strangely.
As we'll see later, the Notes example will point each note object's -context_id to the package instance in which the note was +context_id to the package instance in which the note was created. The idea will be that in a real site, the administrator would create one package instance for every separate set of Notes (say, one per user). The instance would "own" all of the notes that it created, @@ -357,43 +357,43 @@ that the data model is trying to support.
Another less important reason for these two rules is to not introduce -any joins against the acs_objects table in SQL queries in +any joins against the acs_objects table in SQL queries in your application that you do not absolutely need.
In the Notes example, the result of applying these rules is that we -are careful to define our own attribute for owner_id -rather than overloading creation_user from the objects -table. But, since we will probably use creation_date and +are careful to define our own attribute for owner_id +rather than overloading creation_user from the objects +table. But, since we will probably use creation_date and so on for their intended purposes, we don't bother to define our own attributes to store that data again. This will entail joins with -acs_objects but that's OK because it makes the overall +acs_objects but that's OK because it makes the overall data model cleaner. The real lesson is that deciding exactly how and when to use inherited attributes is fairly straightforward, but requires a good amount of thought at design time even for simple applications. -
Hooking into the OpenACS 4.6.3 object system brings the application developer numerous benefits, and doing it involves only four easy steps:
Describe the a new object type to the system. Most new application -types will be subtypes of the built-in type acs_object. +types will be subtypes of the built-in type acs_object.
Define a table to store application object data.
Define a PL/SQL package to store procedures related to the new -type. You have to define at least a function called new +type. You have to define at least a function called new to create new application objects and a procedure called -delete to delete them. +delete to delete them.
Define a package body that contains the implementations of the PL/SQL procedures defined above.
Try not to write queries in your application that join against -acs_objects. This means you should never use the fields -in acs_objects for application-specific purposes. This is -especially true for the context_id field. +acs_objects. This means you should never use the fields +in acs_objects for application-specific purposes. This is +especially true for the context_id field.
($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/openacs-overview.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/openacs-overview.html,v diff -u -r1.3.2.6 -r1.3.2.7 --- openacs-4/packages/acs-core-docs/www/openacs-overview.html 29 Apr 2003 05:58:34 -0000 1.3.2.6 +++ openacs-4/packages/acs-core-docs/www/openacs-overview.html 7 May 2003 17:40:59 -0000 1.3.2.7 @@ -1,5 +1,5 @@ -Overview +
Overview OpenACS (Open Architecture Community System) is an advanced toolkit for building scalable, community-oriented web applications. If you're thinking of building an Index: openacs-4/packages/acs-core-docs/www/openacs.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/openacs.html,v diff -u -r1.6.2.10 -r1.6.2.11 --- openacs-4/packages/acs-core-docs/www/openacs.html 4 May 2003 06:30:02 -0000 1.6.2.10 +++ openacs-4/packages/acs-core-docs/www/openacs.html 7 May 2003 17:40:59 -0000 1.6.2.11 @@ -1,22 +1,22 @@ -
Install OpenACS 4.6.3 +
Install OpenACS 4.6.3 by Vinod Kurup
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -
The reference install stores all OpenACS services in - /web, with one subdirectory per +
The reference install stores all OpenACS services in + /web, with one subdirectory per service. The first time you install a service, you must create - that directory and set its permissions:
[root@yourserver root]# mkdir /web -[root@yourserver root]# chgrp web /web -[root@yourserver root]# chmod 770 /web + that directory and set its permissions:[root@yourserver root]# mkdir /web +[root@yourserver root]# chgrp web /web +[root@yourserver root]# chmod 770 /web [root@yourserver root]# -mkdir /web +mkdir /web chgrp web /web -chmod 770 /web
You should already have downloaded the OpenACS tarball - to the /tmp directory. If +chmod 770 /web
You should already have downloaded the OpenACS tarball + to the /tmp directory. If noot, download the OpenACS tarball and save it in - /tmp and proceed:
+ /tmp and proceed:
AOLserver needs to be started as the root user if you want to use port 80. Once it starts, though, it will drop the root privileges and run as another user, which you must specify on the command line. It's @@ -29,36 +29,36 @@ for each different service. A service name should be a single word, letters and numbers only. If the name of your site is one word, that would be a good choice. For - example "service0" might be the service name for the - service0.net + example "service0" might be the service name for the + service0.net community.
For the 4.6.3-P and 4.6.3-O Reference Platform, - we'll use a server named service0 and - a user named service0. We'll leave the password + we'll use a server named service0 and + a user named service0. We'll leave the password blank for increased security. The only way to log in will be with ssh certificates. The only people who should log in are developers for that specific instance. Add this user, and put - it in the web group so that it + it in the web group so that it can use database commands associated with that group. -
[root@yourserver root]# useradd -g web service0 +[root@yourserver root]# useradd -g web service0 [root@yourserver root]#
Set up database environment variables. They are necessary for working with the database. -
[root@yourserver root]# su - service0 -[service0@yourserver service0]$ emacs .bashrc
Put in the appropriate lines for the database you are running. If you will use both databases, put in both sets of lines.
PostGreSQL:
export LD_LIBRARY_PATH=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pgsql/lib +[root@yourserver root]# su - service0 +[service0@yourserver service0]$ emacs .bashrc
Put in the appropriate lines for the database you are running. If you will use both databases, put in both sets of lines.
PostGreSQL:
export LD_LIBRARY_PATH=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pgsql/lib export PATH=$PATH:/usr/local/pgsql/binOracle. These environment variables are specific for a local Oracle installation communicating via IPC. If you are connecting to a remote Oracle installation, you'll need to adjust these appropriately. Also, make sure that the '8.1.7' matches your Oracle version.
export ORACLE_BASE=/ora8/m01/app/oracle -export ORACLE_HOME=$ORACLE_BASE/product/8.1.7 +export ORACLE_HOME=$ORACLE_BASE/product/8.1.7 export PATH=$PATH:$ORACLE_HOME/bin export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib export ORACLE_SID=ora8 export ORACLE_TERM=vt100 export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/dataTest this by logging out and back in as - service0 and checking the paths.
[service0@yourserver service0]$ exit + service0 and checking the paths.[service0@yourserver service0]$ exit logout -[root@yourserver src]# su - service0 -[postgres@yourserver pgsql]$ env | grep PATH +[root@yourserver src]# su - service0 +[postgres@yourserver pgsql]$ env | grep PATHFor PostGreSQL, you should see:
LD_LIBRARY_PATH=LD_LIBRARY_PATH=:/usr/local/pgsql/lib PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin/X11:/usr/X11R6/bin:/root/bin:/usr/local/pgsql/bin:/usr/local/pgsql/binFor Oracle:
ORACLE_BASE=/ora8/m01/app/oracle @@ -67,104 +67,104 @@ LD_LIBRARY_PATH=/ora8/m01/app/oracle/product/8.1.7/lib:/lib:/usr/lib ORACLE_SID=ora8 ORACLE_TERM=vt100 -ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data[service0@yourserver service0]$ exit +ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data[service0@yourserver service0]$ exit logout -[root@yourserver root]#Unpack the OpenACS tarball and rename it to service0. Secure the directory so that only the owner can access it. Check the permissions by listing the directory.
[root@yourserver root]# su - service0 -[service0@yourserver service0]$ cd /web -[service0@yourserver web]$ tar xzf /tmp/openacs-4.6.3.tgz -[service0@yourserver web]$ mv openacs-4.6.3 service0 -[service0@yourserver web]$ chmod -R 700 service0 -[service0@yourserver web]$ ls -al +[root@yourserver root]#Unpack the OpenACS tarball and rename it to service0. Secure the directory so that only the owner can access it. Check the permissions by listing the directory.
[root@yourserver root]# su - service0 +[service0@yourserver service0]$ cd /web +[service0@yourserver web]$ tar xzf /tmp/openacs-4.6.3.tgz +[service0@yourserver web]$ mv openacs-4.6.3 service0 +[service0@yourserver web]$ chmod -R 700 service0 +[service0@yourserver web]$ ls -al total 3 drwxrwx--- 3 root web 1024 Mar 29 16:41 . drwxr-xr-x 25 root root 1024 Mar 29 16:24 .. drwx------ 7 service0 web 1024 Jan 6 14:36 service0 -[service0@yourserver web]$ exit +[service0@yourserver web]$ exit logout [root@yourserver root]# -su - service0 +su - service0 cd /web tar xzf /tmp/openacs-4.6.3.tgz mv openacs-4.6.3 service0 chmod -R 700 service0/ -exit
Add the Service to CVS - OPTIONAL.�If this is a development server, you may want to add +exit
Add the Service to CVS - OPTIONAL.�If this is a development server, you may want to add it to a CVS - repository..
Create and set permissions on a subdirectory in the local cvs repository.
[root@yourserver root]# mkdir /cvsroot/service0 -[root@yourserver root]# chown service0.web /cvsroot/service0 + repository..
Create and set permissions on a subdirectory in the local cvs repository.
[root@yourserver root]# mkdir /cvsroot/service0 +[root@yourserver root]# chown service0.web /cvsroot/service0 [root@yourserver root]# -mkdir /cvsroot/service0 -chown service0.web /cvsroot/service0Add the repository location to the user environment.
[root@yourserver root]# su - service0 -[service0@yourserver service0]$ emacs .bashrc
Put this string into /home/service0/.bashrc:
export CVSROOT=/cvsroot[service0@yourserver service0]$ exit +mkdir /cvsroot/service0 +chown service0.web /cvsroot/service0
Add the repository location to the user environment.
[root@yourserver root]# su - service0 +[service0@yourserver service0]$ emacs .bashrc
Put this string into /home/service0/.bashrc:
export CVSROOT=/cvsroot[service0@yourserver service0]$ exit logout [root@yourserver root]#Import all files into cvs. In order to work on files with source control, the files must be checked out from cvs. So we will import, move aside, and then check out all of the files. In the cvs import command, - service0 + service0 refers to the cvs repository to use; it uses the CVSROOT plus this string, i.e. - /cvsroot/service0. + /cvsroot/service0. "OpenACS" is the vendor tag, and "openacs-4-6-3" is the release tag. These tags will be useful in upgrading and - branching. -m sets the version comment.
[root@yourserver root]# su - service0 -[service0@yourserver service0]$ cd /web/service0 -[service0@yourserver service0]$ cvs import -m "initial install" service0 OpenACS openacs-4-6-3 -N service0/license.txt -N service0/readme.txt + branching. -m sets the version comment.[root@yourserver root]# su - service0 +[service0@yourserver service0]$ cd /web/service0 +[service0@yourserver service0]$ cvs import -m "initial install" service0 OpenACS openacs-4-6-3 +N service0/license.txt +N service0/readme.txt (many lines omitted) -N service0/www/SYSTEM/flush-memoized-statement.tcl +N service0/www/SYSTEM/flush-memoized-statement.tcl No conflicts created by this import [service0@yourserver service0]$ -su - service0 -cd /web/service0 -cvs import -m "initial install" service0 OpenACS openacs-4-6-3Move the original directory to a temporary location, and check out the cvs repository in its place. If the service starts correctly, come back and remove the temporary copy of the uploaded files.
[service0@yourserver service0]$ cd .. -[service0@yourserver web]$ mv service0 service0.orig -[service0@yourserver web]$ cvs checkout service0 -cvs checkout: Updating service0 -U service0/license.txt +su - service0 +cd /web/service0 +cvs import -m "initial install" service0 OpenACS openacs-4-6-3
Move the original directory to a temporary location, and check out the cvs repository in its place. If the service starts correctly, come back and remove the temporary copy of the uploaded files.
[service0@yourserver service0]$ cd .. +[service0@yourserver web]$ mv service0 service0.orig +[service0@yourserver web]$ cvs checkout service0 +cvs checkout: Updating service0 +U service0/license.txt (many lines omitted) -U service0/www/SYSTEM/dbtest.tcl -U service0/www/SYSTEM/flush-memoized-statement.tcl -[service0@yourserver web]$ exit +U service0/www/SYSTEM/dbtest.tcl +U service0/www/SYSTEM/flush-memoized-statement.tcl +[service0@yourserver web]$ exit logout [root@yourserver web]# -cd .. -mv service0 service0.orig -cvs checkout service0 -exitSet up several additional directories in the service root: - etc is for configuration and control files, log is for error and request (web page hit) log files, and database-backup is for database backup files. If you did the CVS step, note that these new directories are excluded from that step so that you can decide whether or not you want your logs and config files in source control.
[root@yourserver root]# su - service0 -[service0@yourserver service0]$ mkdir /web/service0/etc /web/service0/log /web/service0/database-backup -[service0@yourserver web]$ exit +cd .. +mv service0 service0.orig +cvs checkout service0 +exit
Set up several additional directories in the service root: + etc is for configuration and control files, log is for error and request (web page hit) log files, and database-backup is for database backup files. If you did the CVS step, note that these new directories are excluded from that step so that you can decide whether or not you want your logs and config files in source control.
[root@yourserver root]# su - service0 +[service0@yourserver service0]$ mkdir /web/service0/etc /web/service0/log /web/service0/database-backup +[service0@yourserver web]$ exit logout [root@yourserver web]# -su - service0 -mkdir /web/service0/etc /web/service0/log /web/service0/database-backup -exitOPTIONAL - if you won't be using Oracle, skip to Prepare PostgreSQL for OpenACS
+
su - service0 +mkdir /web/service0/etc /web/service0/log /web/service0/database-backup +exit
OPTIONAL - if you won't be using Oracle, skip to Prepare PostgreSQL for OpenACS
You should be sure that your user account - (e.g. service0) is in the - dba group. + (e.g. service0) is in the + dba group.
Verify membership by typing - groups when you login: + groups when you login:
-service0:~$ groups +service0:~$ groups dba webIf you do not see these groups, take the following action:
-service0:~$ su - +service0:~$ su - Password: ************ -root:~# adduser service0 dba+root:~# adduser service0 dba
If you get an error about an undefined group, then add that group manually: @@ -173,15 +173,15 @@ root:~# groupadd dba root:~# groupadd web
- Make sure to logout as root when + Make sure to logout as root when you are finished with this step and log back in as your regular user.
Connect to Oracle using - svrmgrl and login: + svrmgrl and login:
-service0:~$ svrmgrl +service0:~$ svrmgrl SVRMGR> connect internal Connected.@@ -204,31 +204,31 @@ Using the above output, you should determine where to store your tablespace. As a general rule, you'll want to store your tablespace on a mount point under the - /ora8 directory that is separate + /ora8 directory that is separate from the Oracle system data files. By default, the Oracle system - is on m01, so we will use - m02. This enables your Oracle + is on m01, so we will use + m02. This enables your Oracle system and database files to be on separate disks for optimized performance. For more information on such a configuration, see Chapter 12 of Philip's book. For this example, we'll use - /ora8/m02/oradata/ora8/. + /ora8/m02/oradata/ora8/.
Create the directory for the datafile; to do this, - exit from svrmgrl and login as - root for this step:
+ exit from svrmgrl and login as + root for this step:SVRMGR> exit -service0:~$ su - +service0:~$ su - Password: ************ root:~# mkdir -p /ora8/m02/oradata/ora8/ -root:~# chown service0.web /ora8/m02/oradata/ora8 +root:~# chown service0.web /ora8/m02/oradata/ora8 root:~# chmod 775 /ora8/m02/oradata/ora8 root:~# exit -service0:~$+service0:~$
Create a tablespace for the service. It is important that the - tablespace can autoextend. This + tablespace can autoextend. This allows the tablespace's storage capacity to grow as the size of the data grows. We set the pctincrease to be a very low value so that our extents won't grow geometrically. We do not set @@ -237,11 +237,11 @@ tablespace.
-service0:~$ svrmgrl +service0:~$ svrmgrl SVRMGR> connect internal; -SVRMGR> create tablespace service0 - datafile '/ora8/m02/oradata/ora8/service001.dbf' +SVRMGR> create tablespace service0 + datafile '/ora8/m02/oradata/ora8/service001.dbf' size 50M autoextend on next 10M @@ -250,26 +250,26 @@ uniform size 32K;Create a database user for this service. Give the user access to the tablespace and rights to connect. We'll use - service0password as our password.
+ service0password as our password.
Write down what you specify as service_name - (i.e. service0) and + (i.e. service0) and database_password - (i.e. service0password). You + (i.e. service0password). You will need this information for configuring exports and AOLserver.
-SVRMGR> create user service0 identified by service0password default tablespace service0 -temporary tablespace temp quota unlimited on service0; -SVRMGR> grant connect, resource, ctxapp, javasyspriv, query rewrite to service0; -SVRMGR> revoke unlimited tablespace from service0; -SVRMGR> alter user service0 quota unlimited on service0; +SVRMGR> create user service0 identified by service0password default tablespace service0 +temporary tablespace temp quota unlimited on service0; +SVRMGR> grant connect, resource, ctxapp, javasyspriv, query rewrite to service0; +SVRMGR> revoke unlimited tablespace from service0; +SVRMGR> alter user service0 quota unlimited on service0; SVRMGR> exit;Your table space is now ready. In case you are trying to delete a - previous OpenACS installation, consult these commands in the section called “Deleting a tablespace” below. + previous OpenACS installation, consult these commands in Section�, “Deleting a tablespace” below.
Make sure that you can login to Oracle using your service_name account:
-service0:~$ sqlplus service0/service0password +service0:~$ sqlplus service0/service0password SQL> select sysdate from dual; SYSDATE @@ -280,50 +280,50 @@ You should see today's date in a format 'YYYY-MM-DD.' If you can't login, try redoing step 1 again. If the date is in the wrong format, make sure you followed the steps outlined in - the section called “Troubleshooting Oracle Dates” -
Create a user in the database matching the service name.
[root@yourserver root]# su - postgres -[postgres@yourserver pgsql]$ createuser service0 -Shall the new user be allowed to create databases? (y/n) y -Shall the new user be allowed to create more new users? (y/n) y + Section�, “Troubleshooting Oracle Dates” +
Create a user in the database matching the service name.
[root@yourserver root]# su - postgres +[postgres@yourserver pgsql]$ createuser service0 +Shall the new user be allowed to create databases? (y/n) y +Shall the new user be allowed to create more new users? (y/n) y CREATE USER -[postgres@yourserver pgsql]$ exit +[postgres@yourserver pgsql]$ exit logout -[root@yourserver root]#
Create a database with the same name as our service name, service0.
[root@yourserver root]# su - service0 -[service0@yourserver service0]$ createdb service0 +[root@yourserver root]#Create a database with the same name as our service name, service0.
[root@yourserver root]# su - service0 +[service0@yourserver service0]$ createdb service0 CREATE DATABASE [service0@yourserver service0]$ -su - service0 -createdb service0Automate daily database Vacuuming. This is a process which cleans out discarded data from the database. A quick way to automate vacuuming is to edit the cron file for the database user.
[service0@yourserver service0]$ export EDITOR=emacs;crontab -eAdd this line to the file. The numbers and stars at the beginning are cron columns that specify when the program should be run - in this case, whenever the minute is 0 and the hour is 1, i.e., 1:00 am every day.
0 1 * * * /usr/local/pgsql/bin/vacuumdb --analyze service0
Add Full Text Search Support - OPTIONAL
If you are installing Full Text Search, add required packages to the new database.
[service0@yourserver service0]$ /usr/local/pgsql/bin/psql service0 -f /usr/local/src/postgresql-7.2.4/contrib/tsearch/tsearch.sql +su - service0 +createdb service0
Automate daily database Vacuuming. This is a process which cleans out discarded data from the database. A quick way to automate vacuuming is to edit the cron file for the database user.
[service0@yourserver service0]$ export EDITOR=emacs;crontab -eAdd this line to the file. The numbers and stars at the beginning are cron columns that specify when the program should be run - in this case, whenever the minute is 0 and the hour is 1, i.e., 1:00 am every day.
0 1 * * * /usr/local/pgsql/bin/vacuumdb --analyze service0
Add Full Text Search Support - OPTIONAL
If you are installing Full Text Search, add required packages to the new database.
[service0@yourserver service0]$ /usr/local/pgsql/bin/psql service0 -f /usr/local/src/postgresql-7.2.4/contrib/tsearch/tsearch.sql BEGIN CREATE (many lines omitted) INSERT 0 1 COMMIT -[service0@yourserver service0]$ /usr/local/pgsql/bin/psql service0 -f /usr/local/src/postgresql-7.2.4/contrib/pgsql_contrib_openfts/openfts.sql +[service0@yourserver service0]$ /usr/local/pgsql/bin/psql service0 -f /usr/local/src/postgresql-7.2.4/contrib/pgsql_contrib_openfts/openfts.sql CREATE CREATE [service0@yourserver service0]$ -/usr/local/pgsql/bin/psql service0 -f /usr/local/src/postgresql-7.2.4/contrib/tsearch/tsearch.sql -/usr/local/pgsql/bin/psql service0 -f /usr/local/src/postgresql-7.2.4/contrib/pgsql_contrib_openfts/openfts.sql [service0@yourserver service0]$ exit +/usr/local/pgsql/bin/psql service0 -f /usr/local/src/postgresql-7.2.4/contrib/tsearch/tsearch.sql +/usr/local/pgsql/bin/psql service0 -f /usr/local/src/postgresql-7.2.4/contrib/pgsql_contrib_openfts/openfts.sql
[service0@yourserver service0]$ exit logout -[root@yourserver root]#
The AOLserver architecture lets you run an arbitrary number of virtual servers. A virtual server is an HTTP service running on a specific port, e.g. port 80. In order for OpenACS to work, you - need to configure a virtual server. The Reference Platform uses a configuration file included in the OpenACS tarball. Copy it to the /web/service0/etc directory and open it in an editor to adjust the parameters.
[root@yourserver root]# su - service0 -[service0@yourserver service0]$ cd /web/service0/etc -[service0@yourserver etc]# cp /web/service0/packages/acs-core-docs/www/files/config.tcl.txt config.tcl -[service0@yourserver etc]# emacs config.tcl + need to configure a virtual server. The Reference Platform uses a configuration file included in the OpenACS tarball. Copy it to the /web/service0/etc directory and open it in an editor to adjust the parameters.[root@yourserver root]# su - service0 +[service0@yourserver service0]$ cd /web/service0/etc +[service0@yourserver etc]# cp /web/service0/packages/acs-core-docs/www/files/config.tcl.txt config.tcl +[service0@yourserver etc]# emacs config.tcl- You can continue without changing any values in the file. However, if you don't change address to match the computer's ip address, you won't be able to browse to your server from other machines. + You can continue without changing any values in the file. However, if you don't change address to match the computer's ip address, you won't be able to browse to your server from other machines.
httpport - If you want your server on a different port, enter it here. The Reference Platform port is 8000, which is suitable for development use. Port 80 is the standard http port - it's the port used by your browser when you enter http://yourserver.test. So you should use port 80 for your production site.
httpsport - This is the port for https requests. The Reference Platform https port is 8443. If http port is set to 80, httpsport should be 143 to match the standard.
- address - The IP address of the server. If you are hosting multiple IPs on one computer, this is the address specific to the web site. Each virtual server will ignore any requests directed at other addresses.
server - This is the keyword that, by convention, identifies the service. It is also used as part of the path for the service root, as the name of the user for running the service, as the name of the database, and in various dependent places. The Reference Platform uses service0. + address - The IP address of the server. If you are hosting multiple IPs on one computer, this is the address specific to the web site. Each virtual server will ignore any requests directed at other addresses.
server - This is the keyword that, by convention, identifies the service. It is also used as part of the path for the service root, as the name of the user for running the service, as the name of the database, and in various dependent places. The Reference Platform uses service0.
db_name - In almost all cases, this can be kept as a reference to $server. If for some reason, @@ -337,117 +337,117 @@ AOLServer is very configurable. These settings should get you started, but for more options, read the AOLServer docs. -
OPTIONAL: To run OpenFTS, uncomment this line from config.tcl. (To uncomment a line in a tcl file, remove the # at the beginning of the line.)
#ns_param nsfts ${bindir}/nsfts.soOPTIONAL: To run nsopenssl:
Uncomment this line from config.tcl.
#ns_param nsopenssl ${bindir}/nsopenssl.so -Prepare a certificate directory for the service.
[service0@yourserver etc]$ mkdir /web/service0/etc/certs -[service0@yourserver etc]$ chmod 700 /web/service0/etc/certs +OPTIONAL: To run OpenFTS, uncomment this line from config.tcl. (To uncomment a line in a tcl file, remove the # at the beginning of the line.)
#ns_param nsfts ${bindir}/nsfts.soOPTIONAL: To run nsopenssl:
Uncomment this line from config.tcl.
#ns_param nsopenssl ${bindir}/nsopenssl.so +Prepare a certificate directory for the service.
[service0@yourserver etc]$ mkdir /web/service0/etc/certs +[service0@yourserver etc]$ chmod 700 /web/service0/etc/certs [service0@yourserver etc]$ -mkdir /web/service0/etc/certs -chmod 700 /web/service0/etc/certsIt takes two files to support an SSL connection. The certificate is the public half of the key pair - the server sends the certificate to browser requesting ssl. The key is the private half of the key pair. In addition, the certificate must be signed by Certificate Authority or browsers will protest. Each web browser ships with a built-in list of acceptable Certificate Authorities (CAs) and their keys. Only a site certificate signed by a known and approved CA will work smoothly. Any other certificate will cause browsers to produce some messages or block the site. Unfortunately, getting a site certificate signed by a CA costs money. In this section, we'll generate an unsigned certificate which will work in most browsers, albeit with pop-up messages.
Use an OpenSSL perl script to generate a certificate and key.
[service0@yourserver service0]$ cd /web/service0/etc/certs -[service0@yourserver certs]$ perl /usr/share/ssl/misc/CA -newcert +mkdir /web/service0/etc/certs +chmod 700 /web/service0/etc/certs
It takes two files to support an SSL connection. The certificate is the public half of the key pair - the server sends the certificate to browser requesting ssl. The key is the private half of the key pair. In addition, the certificate must be signed by Certificate Authority or browsers will protest. Each web browser ships with a built-in list of acceptable Certificate Authorities (CAs) and their keys. Only a site certificate signed by a known and approved CA will work smoothly. Any other certificate will cause browsers to produce some messages or block the site. Unfortunately, getting a site certificate signed by a CA costs money. In this section, we'll generate an unsigned certificate which will work in most browsers, albeit with pop-up messages.
Use an OpenSSL perl script to generate a certificate and key.
[service0@yourserver service0]$ cd /web/service0/etc/certs +[service0@yourserver certs]$ perl /usr/share/ssl/misc/CA -newcert Using configuration from /usr/share/ssl/openssl.cnf Generating a 1024 bit RSA private key ...++++++ .......++++++ writing new private key to 'newreq.pem' Enter PEM pass phrase:Enter a pass phrase for the CA certificate. Then, answer the rest of the questions. At the end you should see this:
Certificate (and private key) is in newreq.pem -[service0@yourserver certs]$newreq.pem contains our certificate and private key. The key is protected by a passphrase, which means that we'll have to enter the pass phrase each time the server starts. This is impractical and unnecessary, so we create an unprotected version of the key. Security implication: if anyone gets access to the file keyfile.pem, they effectively own the key as much as you do. Mitigation: don't use this key/cert combo for anything besides providing ssl for the web site.
[root@yourserver misc]# openssl rsa -in newreq.pem -out keyfile.pem +[service0@yourserver certs]$newreq.pem contains our certificate and private key. The key is protected by a passphrase, which means that we'll have to enter the pass phrase each time the server starts. This is impractical and unnecessary, so we create an unprotected version of the key. Security implication: if anyone gets access to the file keyfile.pem, they effectively own the key as much as you do. Mitigation: don't use this key/cert combo for anything besides providing ssl for the web site.
[root@yourserver misc]# openssl rsa -in newreq.pem -out keyfile.pem read RSA key Enter PEM pass phrase: writing RSA key -[service0@yourserver certs]$To create the certificate file, we take the combined file, copy it, and strip out the key.
[service0@yourserver certs]$ cp newreq.pem certfile.pem -[root@yourserver misc]# emacs certfile.pemStrip out the section that looks like
-----BEGIN RSA PRIVATE KEY----- +[service0@yourserver certs]$To create the certificate file, we take the combined file, copy it, and strip out the key.
[service0@yourserver certs]$ cp newreq.pem certfile.pem +[root@yourserver misc]# emacs certfile.pemStrip out the section that looks like
-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,F3EDE7CA1B404997 S/Sd2MYA0JVmQuIt5bYowXR1KYKDka1d3DUgtoVTiFepIRUrMkZlCli08mWVjE6T (11 lines omitted) 1MU24SHLgdTfDJprEdxZOnxajnbxL420xNVc5RRXlJA8Xxhx/HBKTw== ------END RSA PRIVATE KEY-----
Kill any current running AOLserver processes and start a new one. (Note, if you are using Oracle, rather than PostgreSQL, replace - nsd-postgres with - nsd-oracle). If you are using port 80, you must be root for this step.
[service0@yourserver etc]$ killall nsd + nsd-postgres with + nsd-oracle). If you are using port 80, you must be root for this step.[service0@yourserver etc]$ killall nsd nsd: no process killed -[service0@yourserver service0]$ /usr/local/aolserver/bin/nsd-postgres -t /web/service0/etc/config.tcl +[service0@yourserver service0]$ /usr/local/aolserver/bin/nsd-postgres -t /web/service0/etc/config.tcl [service0@yourserver service0]$ [08/Mar/2003:18:13:29][32131.8192][-main-] Notice: nsd.tcl: starting to read config file... [08/Mar/2003:18:13:29][32131.8192][-main-] Notice: nsd.tcl: finished reading config file.Attempt to connect to the service from a web browser as you did You should specify a URL like: -
http://yourserver.test:8000+
http://yourserver.test:8000You should see a page that looks like this. If you imported your files into cvs, now that you know it worked you can erase the temp - directory with rm -rf /web/service0.orig. + directory with rm -rf /web/service0.orig.
If you don't see the login page, view your error log - (/web/service0/log/service0-error.log) + (/web/service0/log/service0-error.log) to make sure the service is starting without any problems. The most common errors here are trying to start a port 80 server while not root, failing to connect because of a firewall, and aolserver failing to start due to permissions errors or missing files. If you need to make changes, don't forget to kill any running servers with - killall nsd. -
OPTIONAL - Automate AOLserver keepalive
Assuming AOLserver started cleanly in the previous step, we'll set it up so that it's always running, and automatically restarts whenever it dies or is stopped. This step is strongly recommended, even for development sites, because it makes install and maintenance much simpler.
The Reference Platform uses Daemontools to control AOLserver. A simpler method, using init, is here.
Daemontools must already be installed. If not, install it.
Each service controlled by daemontools must have a directory in /service. That directory must have a file called run. Daemontools then creates additional files and directories to track status and log. Create the appropriate directory as /web/service0/etc/daemontools, copy the prepared run file, and set permissions. If your server is not called service0, edit /web/service0/etc/run accordingly.
[service0@yourserver log]$ cd /web/service0/etc -[service0@yourserver etc]$ mkdir daemontools -[service0@yourserver etc]$ cp /web/service0/packages/acs-core-docs/www/files/run.txt daemontools/run -[service0@yourserver etc]$ chmod 700 daemontools/run -cd /web/service0/etc + killall nsd. +
OPTIONAL - Automate AOLserver keepalive
Assuming AOLserver started cleanly in the previous step, we'll set it up so that it's always running, and automatically restarts whenever it dies or is stopped. This step is strongly recommended, even for development sites, because it makes install and maintenance much simpler.
The Reference Platform uses Daemontools to control AOLserver. A simpler method, using init, is here.
Daemontools must already be installed. If not, install it.
Each service controlled by daemontools must have a directory in /service. That directory must have a file called run. Daemontools then creates additional files and directories to track status and log. Create the appropriate directory as /web/service0/etc/daemontools, copy the prepared run file, and set permissions. If your server is not called service0, edit /web/service0/etc/run accordingly.
[service0@yourserver log]$ cd /web/service0/etc +[service0@yourserver etc]$ mkdir daemontools +[service0@yourserver etc]$ cp /web/service0/packages/acs-core-docs/www/files/run.txt daemontools/run +[service0@yourserver etc]$ chmod 700 daemontools/run +cd /web/service0/etc mkdir daemontools -cp /web/service0/packages/acs-core-docs/www/files/run.txt daemontools/run -chmod 700 daemontools/run
Kill any existing AOLserver instances. As root, link the daemontools directory into the /service directory. Daemontools' svscan process checks this directory every five seconds, and will quickly execute run.
[service0@yourserver etc]$ killall nsd +cp /web/service0/packages/acs-core-docs/www/files/run.txt daemontools/run +chmod 700 daemontools/run
Kill any existing AOLserver instances. As root, link the daemontools directory into the /service directory. Daemontools' svscan process checks this directory every five seconds, and will quickly execute run.
[service0@yourserver etc]$ killall nsd nsd: no process killed -[service0@yourserver etc]$ exit +[service0@yourserver etc]$ exit -[root@yourserver root]# ln -s /web/service0/etc/daemontools/ /service/service0Verify that AOLserver is running.
[root@yourserver root]# ps -auxw | grep nsd -service0 5562 14.2 6.2 22436 15952 ? S 11:55 0:04 /usr/local/aolserver/bin/nsd -it /web/service0/etc/config.tcl -u serve +[root@yourserver root]# ln -s /web/service0/etc/daemontools/ /service/service0Verify that AOLserver is running.
[root@yourserver root]# ps -auxw | grep nsd +service0 5562 14.2 6.2 22436 15952 ? S 11:55 0:04 /usr/local/aolserver/bin/nsd -it /web/service0/etc/config.tcl -u serve root 5582 0.0 0.2 3276 628 pts/0 S 11:55 0:00 grep nsd -[root@yourserver root]#The user service0 can now control the service service0 with these commands:
+[root@yourserver root]#
The user service0 can now control the service service0 with these commands:
- svc -d /service/service0 - + svc -d /service/service0 - Bring the server down
- svc -u /service/service0 - + svc -u /service/service0 - Start the server up and leave it in keepalive mode.
- svc -o /service/service0 - + svc -o /service/service0 - Start the server up once. Do not restart it if it stops.
- svc -t /service/service0 - + svc -t /service/service0 - Stop and immediately restart the server.
- svc -k /service/service0 - + svc -k /service/service0 - Sends the server a KILL signal. This is like KILL -9. AOLserver exits immediately. If svc -t fails to fully kill AOLserver, use this option. This does not take the server out of keepalive mode, so it should still bounce back up immediately.
At this point, these commands will work only for the - root user. Grant permission for the web group to use svc commands on the service0 server.
[root@yourserver root]# svgroup web /service/service0 -[root@yourserver root]#
Verify that the controls work. You may want to tail -f /web/service0/log/service0-error.log in another window, so you can see what happens when you type these commands. + root user. Grant permission for the web group to use svc commands on the service0 server.
[root@yourserver root]# svgroup web /service/service0 +[root@yourserver root]#
Verify that the controls work. You may want to tail -f /web/service0/log/service0-error.log in another window, so you can see what happens when you type these commands.
Most of this information comes from Tom Jackson's AOLServer+Daemontools Mini-HOWTO. -
Now that you've got AOLserver up and running, let's install OpenACS 4.6.3.
You should see a page from the webserver titled - OpenACS Installation: + OpenACS Installation: Welcome. You will be warned if your version of the database driver is out of date, if AOLserver cannot connect to the database, if any modules are missing or out-of-date, or if there are any problems with filesystem permissions on the server side. But if everything is fine, you can click - Next to proceed to load the + Next to proceed to load the OpenACS Kernel data model.
@@ -460,7 +460,7 @@ Loading package .info files ... this will take a few minutes
This will really take a few minutes. Have faith! Finally, another - Next button will appear at the + Next button will appear at the bottom - click it.
@@ -470,95 +470,95 @@ previously selected packages, but watch out for any errors. Eventually, the page will display "Generating secret tokens" and then "Done"- click - Next. + Next.
You should see a page, "OpenACS Installation: Create Administrator" with form fields to define the OpenACS site administrator. Fill out the fields as appropriate, and click - Create User. + Create User.
You should see a page, "OpenACS Installation: Set System Information" allowing you to name your service. Fill out the - fields as appropriate, and click Set System + fields as appropriate, and click Set System Information
You'll see the final Installer page, "OpenACS Installation: Complete." It will tell you that the server is being restarted; note that unless you already set up a way for AOLServer to restart itself (ie. inittab or daemontools), you'll need to manually restart your service. -
[service0@yourserver service0]$ /usr/local/aolserver/bin/nsd-postgres -t /web/service0/config.tcl
+
[service0@yourserver service0]$ /usr/local/aolserver/bin/nsd-postgres -t /web/service0/config.tcl
Give the server a few minutes to start up. Then reload the final page above. You should see the front page, with an area to login near the upper right. Congratulations, OpenACS 4.6.3 is now up and running! -
OPTIONAL - Install Full Text Search.
Click Package Manager on the right side of the default home page. If prompted, log in with the account and password you entered during install.
Click on the Install -packages link.
On the next screen, after it loads, click on Uncheck all boxes, then click the second checkbox next to OpenFTS Driver 4.2. This will automatically check the first box. Then click Next.
Click Install Packages
Restart the service.
[service0@yourserver service0]$ svc -t /service/service0 -[service0@yourserver service0]$
Wait a minute, then browse back to the home page.
Click on Site Map on the top right side of the screen.
Mount the OpenFTS Full Text Search Engine in the site map.
Click the new sub folder link on the "/" line, the first line under Main Site:/.
Type openfts -and click New.
On the new openfts line, click the mount link.
Click OpenFTS -Driver.
On the openfts line, click set parameters.
Change openfts_tcl_src_path to /usr/local/src/Search-OpenFTS-tcl-0.3.2/ and click Set Parameters +
OPTIONAL - Install Full Text Search.
Click Package Manager on the right side of the default home page. If prompted, log in with the account and password you entered during install.
Click on the Install +packages link.
On the next screen, after it loads, click on Uncheck all boxes, then click the second checkbox next to OpenFTS Driver 4.2. This will automatically check the first box. Then click Next.
Click Install Packages
Restart the service.
[service0@yourserver service0]$ svc -t /service/service0 +[service0@yourserver service0]$
Wait a minute, then browse back to the home page.
Click on Site Map on the top right side of the screen.
Mount the OpenFTS Full Text Search Engine in the site map.
Click the new sub folder link on the "/" line, the first line under Main Site:/.
Type openfts +and click New.
On the new openfts line, click the mount link.
Click OpenFTS +Driver.
On the openfts line, click set parameters.
Change openfts_tcl_src_path to /usr/local/src/Search-OpenFTS-tcl-0.3.2/ and click Set Parameters
Mount the Search interface in the site map.
Click the -new sub folder link on the -Main Site line.
Type search -and click New.
Click the new -application link on the search - line.
Type search +new sub folder link on the +Main Site line.
Type search +and click New.
Click the new +application link on the search + line.
Type search where it says -untitled, choose -search from the +untitled, choose +search from the drop-down list, and click -New. -
Restart the service.
[service0@yourserver service0]$ svc -t /service/service0 -[service0@yourserver service0]$
Wait a minute, then click on Main Site at the top of the page.
Initialize the OpenFTS Engine. This creates a set of tables in the database to support FTS.
Near the bottom of the page, click on the OpenFTS Driver link. Click on Administration. -Click on Initialize OpenFTS Engine. -Click Initialize OpenFTS Engine.
Add the FTS Engine service contract
Click on the Main -Site.
Click on the ACS -Service Contract link near the bottom of the home page.
On the FtsEngineDriver +New. +
Restart the service.
[service0@yourserver service0]$ svc -t /service/service0 +[service0@yourserver service0]$
Wait a minute, then click on Main Site at the top of the page.
Initialize the OpenFTS Engine. This creates a set of tables in the database to support FTS.
Near the bottom of the page, click on the OpenFTS Driver link. Click on Administration. +Click on Initialize OpenFTS Engine. +Click Initialize OpenFTS Engine.
Add the FTS Engine service contract
Click on the Main +Site.
Click on the ACS +Service Contract link near the bottom of the home page.
On the FtsEngineDriver line, click -Install. -
Restart the service.
[service0@yourserver service0]$ svc -t /service/service0 -[service0@yourserver service0]$
Test FTS. (INCOMPLETE). Add a package that supports search,like "note," add some content, and search for it.
This is a very good time to back the service, even if it's not a production service. Making a backup now lets you roll back to this initial, clean setup at any point in the future, without repeating the install process. A full OpenACS service backup includes everything in the /web/service0/ directory. At this point it's probably sufficient to back up just the database, because you can recover the files from a tarball.
Note that, if you did the CVS options in this document, the /web/service0/etc directory is not included in cvs and you may want to add it.
PostGreSQL.�Create a backup file and verify that it was created and has a reasonable size (several megabytes).
[service0@yourserver service0]$ mkdir /web/service0/database-backup -[service0@yourserver service0]$ pg_dump -f /web/service0/database-backup/initial_backup.dmp service0 -[service0@yourserver service0]$ ls -al /web/service0/database-backup +Install. +Restart the service.
[service0@yourserver service0]$ svc -t /service/service0 +[service0@yourserver service0]$
Test FTS. (INCOMPLETE). Add a package that supports search,like "note," add some content, and search for it.
This is a very good time to back the service, even if it's not a production service. Making a backup now lets you roll back to this initial, clean setup at any point in the future, without repeating the install process. A full OpenACS service backup includes everything in the /web/service0/ directory. At this point it's probably sufficient to back up just the database, because you can recover the files from a tarball.
Note that, if you did the CVS options in this document, the /web/service0/etc directory is not included in cvs and you may want to add it.
PostGreSQL.�Create a backup file and verify that it was created and has a reasonable size (several megabytes).
[service0@yourserver service0]$ mkdir /web/service0/database-backup +[service0@yourserver service0]$ pg_dump -f /web/service0/database-backup/initial_backup.dmp service0 +[service0@yourserver service0]$ ls -al /web/service0/database-backup total 1425 -drwxr-xr-x 2 service0 web 1024 Mar 9 14:13 . -drwx------ 11 service0 web 1024 Mar 9 14:11 .. --rw-r--r-- 1 service0 web 1449826 Mar 9 14:13 initial_backup.dmp +drwxr-xr-x 2 service0 web 1024 Mar 9 14:13 . +drwx------ 11 service0 web 1024 Mar 9 14:11 .. +-rw-r--r-- 1 service0 web 1449826 Mar 9 14:13 initial_backup.dmp [service0@yourserver service0]$ -mkdir /web/service0/database-backup -pg_dump -f /web/service0/database-backup/initial_backup.dmp service0 -ls -al /web/service0/database-backupOracle - INCOMPLETE.�
Backup can encompass all files in /web/service0. For a development server, putting the files in cvs is sufficient. (It's important then to back up the cvs repository!)
A quick way to automate database backup is a cron job. This is not recommended for production and is not part of the Reference Platform, because it is not cross-platform and can fail silently. More thorough methods are documented in the section called “Backup Strategy”
[service0@yourserver service0]$ export EDITOR=emacs;crontab -eAdd this line to the file. The numbers and stars at the beginning are cron columns that specify when the program should be run - in this case, whenever the minute is 0 and the hour is 1, i.e., 1:00 am every day.
0 1 * * * /usr/local/pgsql/bin/pg_dump -f /web/service0/database-backup/service0_$(date +%Y-%m-%d).dmp service0If you plan to back up the whole /web/service0 directory, then it would be redundant to keep a history of database backups. In that case, set up the cron job to overwrite the previous backup each time:
0 1 * * * /usr/local/pgsql/bin/pg_dump -f /web/service0/database-backup/service0_nightly.dmp service0Backup can encompass all files in /web/service0. For a development server, putting the files in cvs is sufficient. (It's important then to back up the cvs repository!)
A quick way to automate database backup is a cron job. This is not recommended for production and is not part of the Reference Platform, because it is not cross-platform and can fail silently. More thorough methods are documented in Section�, “Backup Strategy”
[service0@yourserver service0]$ export EDITOR=emacs;crontab -eAdd this line to the file. The numbers and stars at the beginning are cron columns that specify when the program should be run - in this case, whenever the minute is 0 and the hour is 1, i.e., 1:00 am every day.
0 1 * * * /usr/local/pgsql/bin/pg_dump -f /web/service0/database-backup/service0_$(date +%Y-%m-%d).dmp service0If you plan to back up the whole /web/service0 directory, then it would be redundant to keep a history of database backups. In that case, set up the cron job to overwrite the previous backup each time:
0 1 * * * /usr/local/pgsql/bin/pg_dump -f /web/service0/database-backup/service0_nightly.dmp service0Analog is a program with processes webserver access logs, performs DNS lookup, and outputs HTML reports. Analog should already be installed. A modified configuration file is included in - the OpenACS tarball.
[root@yourserver src]# su - service0 -[service0@yourserver service0]$ cd /web/service0 -[service0@yourserver service0]$ cp /web/service0/packages/acs-core-docs/www/files/analog.cfg.txt etc/analog.cfg -[service0@yourserver service0]$ mkdir www/log -[service0@yourserver service0]$ cp -r /usr/share/analog-5.31/images www/log/ -[service0@yourserver service0]$+ the OpenACS tarball.
[root@yourserver src]# su - service0 +[service0@yourserver service0]$ cd /web/service0 +[service0@yourserver service0]$ cp /web/service0/packages/acs-core-docs/www/files/analog.cfg.txt etc/analog.cfg +[service0@yourserver service0]$ mkdir www/log +[service0@yourserver service0]$ cp -r /usr/share/analog-5.31/images www/log/ +[service0@yourserver service0]$su - service0 cd /web/service0 cp /web/service0/packages/acs-core-docs/www/files/analog.cfg.txt etc/analog.cfg mkdir www/log -cp -r /usr/share/analog-5.31/images www/log/
Edit -/web/service0/etc/analog.cfg and change the variable in HOSTNAME "[my +cp -r /usr/share/analog-5.31/images www/log/
Edit +/web/service0/etc/analog.cfg and change the variable in HOSTNAME "[my organisation]" to reflect your website title. If you don't want the traffic log to be publicly visible, change -OUTFILE /web/service0/www/log/traffic.html to use a private -directory.
Run it.
[service0@yourserver service0]$ /usr/share/analog-5.31/analog -G -g/web/service0/etc/analog.cfg +OUTFILE /web/service0/www/log/traffic.html to use a private +directory.Run it.
[service0@yourserver service0]$ /usr/share/analog-5.31/analog -G -g/web/service0/etc/analog.cfg /usr/share/analog-5.31/analog: analog version 5.31/Unix /usr/share/analog-5.31/analog: Warning F: Failed to open DNS input file /home/service0/dnscache: ignoring it (For help on all errors and warnings, see docs/errors.html) /usr/share/analog-5.31/analog: Warning R: Turning off empty Search Word Report -[service0@yourserver service0]$Verify that it works by browing to http://yourserver.test:8000/log/traffic.html
Automate this by creating a file in - /etc/cron.daily.
[service0@yourserver service0]$ exit +[service0@yourserver service0]$Verify that it works by browing to http://yourserver.test:8000/log/traffic.html
Automate this by creating a file in + /etc/cron.daily.
[service0@yourserver service0]$ exit logout -[root@yourserver root]# emacs /etc/cron.daily/analogPut this into the file:
#!/bin/sh +[root@yourserver root]# emacs /etc/cron.daily/analogPut this into the file:
#!/bin/sh -/usr/share/analog-5.31/analog -G -g/web/service0/etc/analog.cfg
[root@yourserver root]# chmod 755 /etc/cron.daily/analogTest it by running the script.
[root@yourserver root]# sh /etc/cron.daily/analogBrowse to http://yourserver.test/log/traffic.html
Test your backup and recovery procedure.
Follow the instruction on the home page to change the appearance of your service or add more packages.
Proceed to the tutorial to learn how to develop your own packages.
($Id$)View comments on this page at openacs.org +/usr/share/analog-5.31/analog -G -g/web/service0/etc/analog.cfg[root@yourserver root]# chmod 755 /etc/cron.daily/analogTest it by running the script.
[root@yourserver root]# sh /etc/cron.daily/analogBrowse to http://yourserver.test/log/traffic.html
Test your backup and recovery procedure.
Follow the instruction on the home page to change the appearance of your service or add more packages.
Proceed to the tutorial to learn how to develop your own packages.
($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/oracle.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/oracle.html,v diff -u -r1.8.2.10 -r1.8.2.11 --- openacs-4/packages/acs-core-docs/www/oracle.html 4 May 2003 06:30:02 -0000 1.8.2.10 +++ openacs-4/packages/acs-core-docs/www/oracle.html 7 May 2003 17:40:59 -0000 1.8.2.11 @@ -1,5 +1,5 @@ -Install Oracle 8.1.7 +
Install Oracle 8.1.7 by Vinod Kurup
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. @@ -17,7 +17,7 @@ box as AOLServer. For more details on a remote Oracle installation, see Daryl Biberdorf's document. -You can obtain the software through a variety of methods (You'll need to become a member of technet.oracle.com, which is @@ -61,34 +61,34 @@ It used to be possible to get a free CD by mail, but I can no longer find the link for that option. -
Throughout these instructions, we will refer to a number of configurable settings and advise certain defaults. With the exception of passwords, we advise you to follow these defaults unless you know what you are doing. Subsequent documents will expect that you used the defaults, so a change made here will necessitate further changes - later. For a guide to the defaults, please see the section called “Defaults”. + later. For a guide to the defaults, please see Section�, “Defaults”.
For additional resources/documentation, please see this thread and Andrew Piskorski's mini-guide.. -
Though Oracle 8.1.7 has an automated installer, we still need to perform several manual, administrative tasks before we can launch it. You must perform all of these steps as the - root user. We recommend entering the - X window system as a normal user and then doing a su + root user. We recommend entering the + X window system as a normal user and then doing a su -. This command gives you full root access.
Login as a non-root user and start X by typing - startx + startx
joeuser:~$ startx@@ -104,12 +104,12 @@
- Create and setup the oracle - group and oracle account + Create and setup the oracle + group and oracle account
- We need to create a user oracle, + We need to create a user oracle, which is used to install the product, as well as starting and stopping the database. @@ -127,13 +127,13 @@ Setup the installation location for Oracle. While Oracle can reside in a variety of places in the file system, OpenACS has - adopted /ora8 as the base + adopted /ora8 as the base directory.
Note: the Oracle install needs - about 1 GB free on /ora8 to + about 1 GB free on /ora8 to install successfully.
@@ -143,22 +143,22 @@ root:/ora8# chown -R oracle.dba /ora8 root:/ora8# exit- Set up the oracle user's + Set up the oracle user's environment
Log in as the user - oracle by typing the + oracle by typing the following:
joeuser:~$ su - oracle Password: ********Use a text editor to edit the - .bash_profile file in the - oracle account home + .bash_profile file in the + oracle account home directory.
@@ -192,7 +192,7 @@ Add the following lines (substituting your Oracle version number as needed) to - .bash_profile: + .bash_profile:export ORACLE_BASE=/ora8/m01/app/oracle @@ -205,9 +205,9 @@ umask 022- Save the file by typing CTRL-X + Save the file by typing CTRL-X CTRL-S and then exit by typing - CTRL-X + CTRL-X CTRL-C. Alternatively, use the menus.
@@ -230,11 +230,11 @@
oracle:~$ exit- Log back in as oracle and double + Log back in as oracle and double check that your environment variables are as intended. The - env command lists all of the + env command lists all of the variables that are set in your environment, and - grep shows you just the lines + grep shows you just the lines you want (those with ORA in it).
@@ -251,47 +251,47 @@ ORA_NLS33=/ora8/m01/app/oracle/product/8.1.7/ocommon/nls/admin/dataIf not, try adding the files to - ~/.bashrc instead of - .bash_profile. Then logout and + ~/.bashrc instead of + .bash_profile. Then logout and log back in again. Also, be certain you are doing - su - oracle and not just - su oracle. The - - means that - .bashrc and - .bash_profile will be + su - oracle and not just + su oracle. The + - means that + .bashrc and + .bash_profile will be evaluated.
- Make sure that /bin, - /usr/bin, and - /usr/local/bin are in your path + Make sure that /bin, + /usr/bin, and + /usr/local/bin are in your path by typing:
oracle:~$ echo $PATH /bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin:/home/oracle/bin:/ora8/m01/app/oracle/product/8.1.7/binIf they are not, then add them to the - .bash_profile by changing the + .bash_profile by changing the PATH statement above to - PATH=$PATH:/usr/local/bin:$ORACLE_HOME/bin + PATH=$PATH:/usr/local/bin:$ORACLE_HOME/bin -
+ Log in as oracle and start X if not already running. Start a new terminal:
joeuser:~$ xhost +localhost joeuser:~$ su - oracle Password: ********** oracle:~$ export DISPLAY=localhost:0.0- Find the runInstaller script + Find the runInstaller script
If you are installing Oracle from a CD-ROM, it is located in - the install/linux path from + the install/linux path from the cd-rom mount point
@@ -301,7 +301,7 @@ oracle:~$ cd /mnt/cdromIf you are installing from the tarball, the install script is - located in the Oracle8iR2 + located in the Oracle8iR2 directory that was created when you expanded the archive.
@@ -314,7 +314,7 @@ doc index.htm install runInstaller stage starterdbIf you don't see - runInstaller, you are in the + runInstaller, you are in the wrong directory.
@@ -326,21 +326,21 @@ A window will open that welcomes you to the 'Oracle Universal Installer' (OUI). Click on - "Next" + "Next"
Note
Some people have had trouble with this step on RedHat 7.3 and 8.0. If so, try the following steps before calling - ./runInstaller: + ./runInstaller:
Execute the following command: - /usr/i386-glib21-linux/bin/i386-glibc21-linux-env.sh + /usr/i386-glib21-linux/bin/i386-glibc21-linux-env.sh
- Type export LD_ASSUME_KERNEL=2.2.5 + Type export LD_ASSUME_KERNEL=2.2.5
@@ -350,21 +350,21 @@ "Source" path should have been prefilled with "(wherever you mounted the - CDROM)/stage/products.jar" + CDROM)/stage/products.jar"
"destination" path says - "/ora8/m01/app/oracle/product/8.1.7" + "/ora8/m01/app/oracle/product/8.1.7"
If the destination is not correct it is because your environment variables are not set properly. Make sure you - logged on as oracle using - su - oracle. If so, edit the - ~/.bash_profile as you - did in the section called “Pre-Installation Tasks” + logged on as oracle using + su - oracle. If so, edit the + ~/.bash_profile as you + did in Section�, “Pre-Installation Tasks”
@@ -378,16 +378,16 @@
Debian users need to link - /bin/awk to - /usr/bin/awk before + /bin/awk to + /usr/bin/awk before running the script below
joueser:~$ su - root:~# ln -s /usr/bin/awk /bin/awk
The Unix Group name needs to be set to - 'oinstall' ( we made + 'oinstall' ( we made this Unix group earlier ).
@@ -466,7 +466,7 @@ Click on the "Java Runtime Environment 1.1.8" It should have the path - "/ora8/m01/app/oracle/jre/1.1.8" + "/ora8/m01/app/oracle/jre/1.1.8"
@@ -513,7 +513,7 @@
- Keep the default path: /usr/local/java + Keep the default path: /usr/local/java
@@ -565,11 +565,11 @@
A "Setup Privileges" window will popup towards the end of the installation asking you to run a script as - root + root
Run the script. Switch to the oracle user first to set the environment appropriately and then do - su to get root privileges, while keeping + su to get root privileges, while keeping the oracle user's enviroment.
joeuser:~$ su - oracle @@ -590,7 +590,7 @@ Enter the full pathname of the local bin directory: [/usr/local/bin]: -Press ENTER here to accept default of /usr/local/bin +Press ENTER here to accept default of /usr/local/bin Creating /etc/oratab file... @@ -688,13 +688,13 @@ Congratulations, you have just installed Oracle 8.1.7 Server! However, you still need to create a database which can take about an hour of non-interactive time, so don't quit yet. -This step will take you through the steps of creating a customized database. Be warned that this process takes about an hour on a Pentium II with 128 MB of RAM. -
Note
RedHat 7.3 and 8.0 users: Before running dbassist, do the following.
+
Note
RedHat 7.3 and 8.0 users: Before running dbassist, do the following.
Download the glibc - patch from Oracle Technet into /tmp. + patch from Oracle Technet into /tmp.
cd $ORACLE_HOME
@@ -703,8 +703,8 @@ ./setup_stubs
Make sure you are running X. Open up a terminal and - su to oracle and then run the - dbassist program. + su to oracle and then run the + dbassist program.
joeuser:~$ xhost +localhost joeuser:~$ su - oracle @@ -736,111 +736,111 @@Click "Next"
- Select "Dedicated Server + Select "Dedicated Server Mode", click - "Next" + "Next"
Accept all of the options, and click - "Next" Oracle Visual + "Next" Oracle Visual Information Retrieval may be grayed out. If so, you can ignore it; just make sure that everything else is checked.
For "Global Database Name", enter - "ora8"; for + "ora8"; for "SID", also enter - "ora8" (it should do + "ora8" (it should do this automatically). Click - "Next". + "Next".
Accept the defaults for the next screen (control file location). Click - "Next" + "Next"
Go to the "temporary" and "rollback" tabs, and change the Size (upper-right text box) to - 150MB. Click - "Next" + 150MB. Click + "Next"
Increase the redo log sizes to - 10000K each. Click - "Next" + 10000K each. Click + "Next"
Use the default checkpoint interval & timeout. Click - "Next" + "Next"
- Increase "Processes" - to 100; - "Block Size" to - 4096 (better for small Linux + Increase "Processes" + to 100; + "Block Size" to + 4096 (better for small Linux boxes; use 8192 for a big Solaris machine).
Accept the defaults for the Trace File Directory. Click - "Next" + "Next"
- Finally, select "Save information to a shell + Finally, select "Save information to a shell script" and click - "Finish" (We're + "Finish" (We're going to examine the contents of this file before creating our database.)
- Click the "Save" + Click the "Save" button. Oracle will automatically save it to the correct directory and with the correct file name. This will likely be - /ora8/m01/app/oracle/product/8.1.7/assistants/dbca/jlib/sqlora8.sh + /ora8/m01/app/oracle/product/8.1.7/assistants/dbca/jlib/sqlora8.sh
It will alert you that the script has been saved successfully.
Now we need to customize the database configuration a bit. While - still logged on as oracle, edit + still logged on as oracle, edit the database initialization script (run when the db loads). The scripts are kept in - $ORACLE_HOME/dbs and the name of + $ORACLE_HOME/dbs and the name of the script is usually - initSID.ora + initSID.ora where SID is the SID of your database. Assuming your - $ORACLE_HOME matches our default + $ORACLE_HOME matches our default of - /ora8/m01/app/oracle/product/8.1.7, + /ora8/m01/app/oracle/product/8.1.7, the following will open the file for editing.
oracle:~$ emacs /ora8/m01/app/oracle/product/8.1.7/dbs/initora8.oraAdd the following line to the end:
nls_date_format = "YYYY-MM-DD"- Now find the open_cursors line + Now find the open_cursors line in the file. If you're using - emacs scroll up to the top of - the buffer and do CTRL-S and - type open_cursors to find the - line. The default is 100. Change - it to 500. + emacs scroll up to the top of + the buffer and do CTRL-S and + type open_cursors to find the + line. The default is 100. Change + it to 500.
open_cursors = 500- Save the file. In emacs, do CTRL-X + Save the file. In emacs, do CTRL-X CTRL-S to save followed by - CTRL-X CTRL-C to exit or use + CTRL-X CTRL-C to exit or use the menu.
At this point, you are ready to initiate database creation. We recommend shutting down X to free up some RAM unless you have 256 MB of RAM or more. You can do this quickly by doing a - CRTL-ALT-BACKSPACE, but make + CRTL-ALT-BACKSPACE, but make sure you have saved any files you were editing. You should now be returned to a text shell prompt. If you get sent to a graphical login screen instead, switch to a virtual console by doing - CRTL-ALT-F1. Then login as - oracle. + CRTL-ALT-F1. Then login as + oracle.
Change to the directory where the database creation script is and run it:
oracle:~$ cd /ora8/m01/app/oracle/product/8.1.7/assistants/dbca/jlib oracle:/ora8/m01/app/oracle/product/8.1.7/assistants/dbca/jlib$ ./sqlora8.shIn some instances, Oracle will save the file to - /ora8/m01/app/oracle/product/8.1.7/assistants/dbca + /ora8/m01/app/oracle/product/8.1.7/assistants/dbca Try running the script there if your first attempt does not succeed.
@@ -851,15 +851,15 @@
Eventually, you'll be returned to your shell prompt. In the meantime, relax, you've earned it. -
For this step, open up a terminal and - su to - oracle as usual. You should be + su to + oracle as usual. You should be running X and Netscape (or other web browser) for this phase.
You need to download the "Oracle Acceptance Test" file. It's available here and at http://philip.greenspun.com/wtr/oracle/acceptance-sql.txt. - Save the file to /tmp + Save the file to /tmp
In the oracle shell, copy the file.
@@ -868,10 +868,10 @@ your term and type the following:oracle:~$ sqlplus system/manager- SQL*Plus should startup. If you get an ORA-01034: + SQL*Plus should startup. If you get an ORA-01034: Oracle not Available error, it is because your Oracle instance is not running. You can manually start it as - the oracle user.
+ the oracle user.oracle:~$ svrmgrl SVRMGR> connect internal SVRMGR> startup@@ -886,7 +886,7 @@
SQL> select sysdate from dual;If you don't see a date that fits the format - YYYY-MM-DD, please read the section called “Troubleshooting Oracle Dates”. + YYYY-MM-DD, please read Section�, “Troubleshooting Oracle Dates”.
At this point we are going to hammer your database with an intense acceptance test. This usually takes around 30 minutes. @@ -901,7 +901,7 @@ 2000-06-10 SQL>
- Many people encounter an error regarding maximum + Many people encounter an error regarding maximum key length:
ERROR at line 1: @@ -910,43 +910,43 @@ usually suffered by people trying to load OpenACS into a pre-existing database. Unfortunately, the only solution is to create a new database with a block size of at least - 4096. For instructions on how to - do this, see the section called “Creating the First Database” above. You + 4096. For instructions on how to + do this, see Section�, “Creating the First Database” above. You can set the parameter using the - dbassist program or by setting - the DB_BLOCK_SIZE parameter in + dbassist program or by setting + the DB_BLOCK_SIZE parameter in your database's creation script.If there were no errors, then consider yourself fortunate. Your Oracle installation is working. -
You will want to automate the database startup and shutdown process. It's probably best to have Oracle spring to life when you boot up your machine.
Oracle includes a script called - dbstart that can be used to + dbstart that can be used to automatically start the database. Unfortunately, the script shipped in the Linux distribution does not work out of the box. The fix is simple. Follow these directions to apply it. First, save dbstart to - /tmp. Then, as - oracle, do the following: + /tmp. Then, as + oracle, do the following:
oracle:~$ cp /tmp/dbstart.txt /ora8/m01/app/oracle/product/8.1.7/bin/dbstart oracle:~$ chmod 755 /ora8/m01/app/oracle/product/8.1.7/bin/dbstartWhile you're logged in as - oracle, you should configure the - oratab file to load your + oracle, you should configure the + oratab file to load your database at start. Edit the file - /etc/oratab: + /etc/oratab:
You will see this line.
ora8:/ora8/m01/app/oracle/product/8.1.7:NBy the way, if you changed the service name or have multiple databases, the format of this file is:
- service_name:$ORACLE_HOME:Y || N + service_name:$ORACLE_HOME:Y || N (for autoload)
Change the last letter from "N" to @@ -957,19 +957,19 @@ Save the file & quit the terminal.
You need a script to automate startup and shutdown. Save oracle8i.txt in - /tmp. Then login as - root and install the + /tmp. Then login as + root and install the script. (Debian users: substitute - /etc/init.d for - /etc/rc.d/init.d throughout + /etc/init.d for + /etc/rc.d/init.d throughout this section)
oracle:~$ su - root:~# cp /tmp/oracle8i.txt /etc/rc.d/init.d/oracle8i root:~# chown root.root /etc/rc.d/init.d/oracle8i root:~# chmod 700 /etc/rc.d/init.d/oracle8iTest the script by typing the following commands and checking the - output. (Debian Users: as root, do mkdir + output. (Debian Users: as root, do mkdir /var/lock/subsys first)
root:~# /etc/rc.d/init.d/oracle8i stop @@ -1079,7 +1079,7 @@ and full site search.Download these three scripts into - /tmp + /tmp
@@ -1088,7 +1088,7 @@ listener8i.txt
Now issue the following commands (still as - root). + root).
root:~# su - oracle oracle:~$ cp /tmp/startlsnr.txt /ora8/m01/app/oracle/product/8.1.7/bin/startlsnr @@ -1148,8 +1148,8 @@ normally. Login into the database using the listener naming convention.- sqlplus - username/password/@SID + sqlplus + username/password/@SID
root:~# su - oracle oracle:~$ sqlplus system/alexisahunk@ora8 @@ -1163,15 +1163,15 @@ SQL> exit oracle:~$ exit root:~#
RedHat users:
- Now run chkconfig on the - listener8i script. + Now run chkconfig on the + listener8i script.
root:~# cd /etc/rc.d/init.d/ root:/etc/rc.d/init.d# chkconfig --add listener8i root:/etc/rc.d/init.d# chkconfig --list listener8i listener8i 0:off 1:off 2:off 3:on 4:on 5:on 6:offDebian users:
- Now run update-rc.d on the - listener8i script. + Now run update-rc.d on the + listener8i script.
root:~# update-rc.d listener8i defaults 21 19 Adding system startup for /etc/init.d/listener8i ... @@ -1196,30 +1196,30 @@ SQL> exitCongratulations, your installation of Oracle 8.1.7 is complete. -
Oracle has an internal representation for storing the data based on the number of seconds elapsed since some date. However, for the purposes of inputing dates into Oracle and getting them back out, Oracle needs to be told to use a specific date format. By default, it uses an Oracle-specific format which isn't copacetic. You want Oracle to use the ANSI-compliant date format which is of form - 'YYYY-MM-DD'. + 'YYYY-MM-DD'.
To fix this, you should include the following line in - $ORACLE_HOME/dbs/initSID.ora + $ORACLE_HOME/dbs/initSID.ora or for the default case, - $ORACLE_HOME/dbs/initora8.ora + $ORACLE_HOME/dbs/initora8.ora
nls_date_format = "YYYY-MM-DD"You test whether this solved the problem by firing up - sqlplus and typing: + sqlplus and typing:
SQL> select sysdate from dual;You should see back a date like - 2000-06-02. If some of the date is - chopped off, i.e. like 2000-06-0, + 2000-06-02. If some of the date is + chopped off, i.e. like 2000-06-0, everything is still fine. The problem here is that - sqlplus is simply truncating the + sqlplus is simply truncating the output. You can fix this by typing:
SQL> column sysdate format a15 @@ -1246,13 +1246,13 @@ Setting this environment variable will override the date setting. Either delete this line and login again or add the following entry to your login scripts after the - nls_lang line: + nls_lang line:export nls_date_format = 'YYYY-MM-DD'Log back in again. If adding the - nls_date_format line doesn't + nls_date_format line doesn't help, you can ask for advice in our OpenACS forum. -
+
Dropping a tablespace
Run sqlplus as the dba: @@ -1269,9 +1269,9 @@
SQL> drop tablespace table_space_name including contents cascade constraints;
For more information on Oracle, please consult the documentation. -
We used the following defaults while installing Oracle.
Variable Value Reason ORACLE_HOME /ora8/m01/app/oracle/product/8.1.7 This is the default Oracle installation directory. ORACLE_SERVICE ora8 The service name is a domain-qualified identifier for + We used the following defaults while installing Oracle.
Variable Value Reason ORACLE_HOME /ora8/m01/app/oracle/product/8.1.7 This is the default Oracle installation directory. ORACLE_SERVICE ora8 The service name is a domain-qualified identifier for your Oracle server. ORACLE_SID ora8 This is an identifier for your Oracle server. ORACLE_OWNER oracle The user who owns all of the oracle files. ORACLE_GROUP dba The special oracle group. Users in the dba group are - authorized to do a connect + authorized to do a connect internal within - svrmgrl to gain full system + svrmgrl to gain full system access to the Oracle system. ($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/packages.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/packages.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/packages.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/packages.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,20 +1,20 @@ -OpenACS 4.6.3 Packages +
OpenACS 4.6.3 Packages By Pete Su and Bryan Quinn
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -This document is a guide on how to write a software package for OpenACS. OpenACS packages are installed and maintained with the OpenACS Package Manager (APM). This document presents reasons for packaging software, conventions for the file system and naming that must be followed, and step by step instructions for creating a new package for the "Notes" example package. -
To answer this question, we should examine how OpenACS servers were organized in the past. We will assume throughout this document that - the page root for your server is called ROOT. In OpenACS + the page root for your server is called ROOT. In OpenACS 3.2.x and earlier, a typical server might have a file system behind it that looked something like this:
@@ -52,8 +52,8 @@In previous versions of OpenACS, you wrote a new application like this:
Put all Tcl library procedures under - server-root/tcl.
Put all User viewable content under - server-root/www.
Put all Admin content under /admin/package-key/. + server-root/tcl.
Put all User viewable content under + server-root/www.
Put all Admin content under /admin/package-key/.
This structure is very simple, and worked well in a world where OpenACS was basically a single monolithic entity. But, this organization @@ -105,7 +105,7 @@ misc pages
Note that a major reorganization has happened here. The diagram only - expands the structure of the bboard/ package directory, + expands the structure of the bboard/ package directory, but all the others are basically the same. Each package encapsulates all of its data model, library code, logic, adminstration pages and user pages in a single part of the file tree. This organization has @@ -126,7 +126,7 @@ package. While we're at it, this tool should also automate package installation, dependency checking, upgrades, and package removal. In OpenACS 4.6.3, this tool is called the APM. -
The APM is used to create, maintain, and install packages. It takes care of copying all of the files and registering the package in the system. The APM is responsible for: @@ -154,7 +154,7 @@
We will also discuss how to organize your files and queries so they work with the OpenACS Query Dispatcher. -
To illustrate the general structure of a package, let's see what the package for the "notes" application should look like. This is shown in @@ -216,7 +216,7 @@
All file locations are relative to the package root, which in this - case is ROOT/packages/notes. The following table + case is ROOT/packages/notes. The following table describes in detail what each of the files up in the diagram contain.
File Type Its Use Naming Convention Data Model Creation Script Contains the SQL that creates the necessary data model and @@ -226,11 +226,11 @@ the script must be under the appropriate directory for the database you are developing your package for (hopefully all OpenACS-supported databases :-)) - sql/<database>/notes-create.sql Data Model Drop Script Contains the SQL that removes the data model and PL/SQL + sql/<database>/notes-create.sql Data Model Drop Script Contains the SQL that removes the data model and PL/SQL packages generated by the creation script. The name must match the convention below or the package will not be installed correctly. - sql/<database>/notes-drop.sql Data Model File Any .sql file that does not match the naming convention above + sql/<database>/notes-drop.sql Data Model File Any .sql file that does not match the naming convention above is recognized as a data model file. It is useful to separate the SQL in the creation and drop scripts into several files and then have the scripts source the other data model @@ -239,71 +239,71 @@ scripts. See the Oracle SQL*Plus documentation for examples. In PostgreSQL the same is acomplished by including \i. - sql/<database>/*.sql Data Model Upgrade Scripts + sql/<database>/*.sql Data Model Upgrade Scripts Contain changes to the data model between versions. The APM can automatically load the appropriate upgrade scripts when upgrading to a new version of a package. - sql/<database>/upgrade/upgrade-<old>-<new>.sql + sql/<database>/upgrade/upgrade-<old>-<new>.sql SQL92 Query Files Files with queries that are supported by all databases. These are usually SQL92 queries. Notice that the .xql filename must match the name of the .tcl file that uses those queries. - + *.xql Oracle-specific Query Files Files with queries that are Oracle-specific. Notice that the .xql filename must match the name of the .tcl file that uses those queries. - + *-oracle.xql PostgreSQL-specific Query Files Files with queries that are PostgreSQL-specific. Notice that the .xql filename must match the name of the .tcl file that uses those queries. - + *-postgresql.xql Tcl Library Files The Tcl library files include a set of procedures that provide an application programming interface (API) for the package to utilize. - tcl/notes-procs.tcl Tcl Initialization The initialization files are used to run Tcl procedures that + tcl/notes-procs.tcl Tcl Initialization The initialization files are used to run Tcl procedures that should only be sourced once on startup. Examples of statements to put here are registered filters or procedures. Tcl initialization files are sourced once on server startup after all of the Tcl library files are sourced. - tcl/notes-init.tcl Administration UI The administration UI is used to administer the instances of + tcl/notes-init.tcl Administration UI The administration UI is used to administer the instances of the package. For example, the bboard administration UI is used to create new forums, moderate postings, and create new - categories for bboard postings. www/admin/* Administration UI Index Page Every package administration UI must have an index page. In - most cases, this is index.tcl but it can be - any file with the name index, such as - index.html or index.adp. www/admin/index.tcl Regression Tests Every package should have a set of regression tests that + categories for bboard postings. www/admin/* Administration UI Index Page Every package administration UI must have an index page. In + most cases, this is index.tcl but it can be + any file with the name index, such as + index.html or index.adp. www/admin/index.tcl Regression Tests Every package should have a set of regression tests that verify that it is in working operation. These tests should be able to be run at any time after the package has been installed and report helpful error messages when there is - a fault in the system. www/admin/tests/ Regression Test Index Page The regression test directory must have an index page that + a fault in the system. www/admin/tests/ Regression Test Index Page The regression test directory must have an index page that displays all of the tests available and provides information on how to run them. This file can have any extension, as long - as its name is index. /www/admin/tests/index.html Documentation Every package must include a full set of documentation that + as its name is index. /www/admin/tests/index.html Documentation Every package must include a full set of documentation that includes requirements and design documents, and user-level and - developer-level documentation where appropriate. /www/doc/ Documentation Index Page The documentation directory must include a static HTML file with the name - of index.html. /www/doc/index.html UI Logic Scripts Packages provide a UI for users to access the system. The UI + developer-level documentation where appropriate. /www/doc/ Documentation Index Page The documentation directory must include a static HTML file with the name + of index.html. /www/doc/index.html UI Logic Scripts Packages provide a UI for users to access the system. The UI is split into Logic and Templates. The logic scripts perform database queries and prepare variables for - presentation by the associated templates. /www/*.tcl UI Templates Templates are used to control the presentation of the UI. + presentation by the associated templates. /www/*.tcl UI Templates Templates are used to control the presentation of the UI. Templates receive a set of data sources from the logic scripts - and prepare them for display to the browser. /www/*.adp UI Index Page The UI must have an index page composed of a logic script - called index.tcl and a template called - index.adp. /www/index.tcl Package Specification File The package specification file is an XML file generated and + and prepare them for display to the browser. /www/*.adp UI Index Page The UI must have an index page composed of a logic script + called index.tcl and a template called + index.adp. /www/index.tcl Package Specification File The package specification file is an XML file generated and maintained by the OpenACS Package Manager (APM). It specifies information about the package including its parameters and its - files. notes.info notes.info Here is how you make a package.
Login as a site-wide administrator on your web service.
Go to the package manager on your server. The URL is /acs-admin/apm. @@ -318,9 +318,9 @@ distinguish it from all the others. It is used as a database key to keep track of the package and as the name of the directory in the file system where all the files related to your package will live. Example - package keys in the current system include: bboard, - acs-kernel and so on. For the example application, we - will use the package key notes. + package keys in the current system include: bboard, + acs-kernel and so on. For the example application, we + will use the package key notes.
- Package Name
This is a short human readable name for your package. For our example, @@ -337,8 +337,8 @@ Generally we think of packages as either being applications, meaning that the package is meant primarily for use by end-users, or services meaning that the package is meant to be a reusable - library of code, to be used by other packages. bboard is - a good example of an application, while acs-templating is + library of code, to be used by other packages. bboard is + a good example of an application, while acs-templating is a good example of a service. Our example is an application, so pick that.
- Package URL @@ -359,40 +359,40 @@
Click the button "Create Package".
At this point, APM will create a directory called - ROOT/packages/notes. + ROOT/packages/notes.
The directory that APM created will be empty except for the - notes.info file. Create a file + notes.info file. Create a file called - ROOT/packages/notes/sql/oracle/notes-create.sql. We'll + ROOT/packages/notes/sql/oracle/notes-create.sql. We'll fill this file with our data model very soon. Create a file called - ROOT/packages/notes/sql/oracle/notes-drop.sql. This + ROOT/packages/notes/sql/oracle/notes-drop.sql. This will contain the instructions to drop the data model. To be complete, you would also create the PostgreSQL versions of these files as well in - ROOT/packages/notes/sql/postgresql/notes-create.sql + ROOT/packages/notes/sql/postgresql/notes-create.sql and - ROOT/packages/notes/sql/postgresql/notes-drop.sql. + ROOT/packages/notes/sql/postgresql/notes-drop.sql.
After you do this, go back to the main APM page. From there, click the link called "notes" to go to the management page for the new package. Now click the link called "Manage file information", then the "Scan the - packages/notes directory for + packages/notes directory for additional files in this package" link on that page to scan the file system for new files. This will bring you do a page that lists all the files you just added and lets you add them to - the notes package. + the notes package.
- Note that while the .sql files + Note that while the .sql files have been added to the packge, they have not been loaded into the database. For the purposes of development, you have to load the data model by hand, because while OpenACS has automatic mechanisms for loading and reloading - .tcl files for code, it does not + .tcl files for code, it does not do the same thing for data model files. -
Now go back to the main management page for the notes +
Now go back to the main management page for the notes If your package has parameters, create them using the "Manage Parameter Information" link.
The new package has been created and installed in the server. At this point, you should add your package files to your CVS repository. @@ -414,23 +414,23 @@
Now you can start developing the package. In addition to writing code, you should also consider the tasks outlined in the package submission guidelines. -
At this point, you are probably excited to see your new package in action. But, we haven't added any user visible pages yet. By convention, user visible pages go in the - ROOT/packages/notes/www directory. So go there and add a - file called hello.html with some text in it. Now we have + ROOT/packages/notes/www directory. So go there and add a + file called hello.html with some text in it. Now we have to make the user pages visible in the site. Since we didn't put the - pages underneath ROOT/www they will not appear on their + pages underneath ROOT/www they will not appear on their own. What we have to do is mount the application into the site map. That is, we have to define the URL from which the application will serve its pages. This process is slightly more complex than in OpenACS 3.x, but also much more flexible.
In OpenACS 3.x, everything in the site was implicitly mounted underneath - ROOT/www. AOLserver automatically took any URL like - /foo/bar/moo/baz.html and mapped it to the file - ROOT/www/foo/bar/moo/baz.html. This was conveniently + ROOT/www. AOLserver automatically took any URL like + /foo/bar/moo/baz.html and mapped it to the file + ROOT/www/foo/bar/moo/baz.html. This was conveniently simple, but lacked flexibility. In particular, it was difficult to map content that lived outside the page root into the site, and it was also hard to map mulitiple URLs to the same place in the file system. @@ -443,8 +443,8 @@ us to easily map package instances to URLs. As we said before, each instance of an application has its own set of parameters and runs from its own URL within the site. What this means is that even - though all the code for the notes application lives in - ROOT/packages/notes, the application itself can run from + though all the code for the notes application lives in + ROOT/packages/notes, the application itself can run from any number of locations in the site. This allows developers and administrators to build sites that look to the user like a collection of many indedendent applications that actually run on a single shared @@ -453,14 +453,14 @@ requested by the user at any given time. The page development tutorial shows you how to use this information in your user interface.
- In order to make the new notes application visible to + In order to make the new notes application visible to users, we have to mount it in the site map. You do this by going to the Site Map page, which is by - default available at /acs-admin/site-map. Use the - interface here to add a new sub-folder called notes to + default available at /acs-admin/site-map. Use the + interface here to add a new sub-folder called notes to the root of the site, then click "new application" to mount a new - instance of the notes application to the site. Name the - new instance notes-1. + instance of the notes application to the site. Name the + new instance notes-1.
Then type this URL into your browser: @@ -470,15 +470,15 @@
Now you should see the contents of the page that you added. What has - happened is that all URLs that start with /notes have + happened is that all URLs that start with /notes have been mapped in such a way as to serve content from the directory - ROOT/packages/notes/www. At this point, you can + ROOT/packages/notes/www. At this point, you can experiment with the site map by mounting multiple instances of the not yet written Notes application at various places in the site. In a later document, we'll see how to write your application so that the code can detect from what URL it was invoked. This is the key to supporting subsites. -
The APM performs the following tasks in an OpenACS site:
Manages creation, installation, and removal of packages from the @@ -493,4 +493,4 @@
Writes out package distribution files for other people to download and install. We'll cover this later. -
Prev Home Next Chapter�9.�Development Reference Up OpenACS 4.6.3 Data Models and the Object System
docs@openacs.orgView comments on this page at openacs.org +
Prev Home Next Chapter�9.�Development Reference Up OpenACS 4.6.3 Data Models and the Object System
docs@openacs.orgView comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/parties.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/parties.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/parties.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/parties.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,9 +1,9 @@ -Parties in OpenACS 4.6.3 +
Parties in OpenACS 4.6.3 by Rafael H. Schloming
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -While many applications must deal with individuals and many applications must deal with groups, most applications must deal with individuals or groups. It is often the case with such applications that in many respects both individuals and groups are treated in an identical manner. It @@ -15,7 +15,7 @@ in a common address book. A typical person's address book might contain the address of his doctor, and his cable company. So what do we label the first field in an entry in his address book? It isn't a person, and it -isn't a company. It is a "party".
Most developers who do significant work with the OpenACS will become +isn't a company. It is a "party".
Most developers who do significant work with the OpenACS will become intimately familiar with the parties data model, and probably extend it on many occasions. For this reason the parties developer guide will begin with an introduction to the data model.
Parties
The central table in the parties data model is the parties table itself. @@ -24,7 +24,7 @@ permissions may granted and revoked on parties and auditing information is stored in the acs objects table.
-create table parties ( +create table parties ( party_id not null constraint parties_party_id_fk references acs_objects (object_id) @@ -47,7 +47,7 @@ Also note that an individual need not be known to the system as a user. A user is in fact a further specialized form of an individual.-create table persons ( +create table persons ( person_id not null constraint persons_person_id_fk references parties (party_id) @@ -73,7 +73,7 @@ only references the users table in situations where it is clear that the references is to a user and not to an individual.-create table users ( +create table users ( user_id not null constraint users_user_id_fk references persons (person_id) @@ -107,7 +107,7 @@ is another piece to the groups data model that records relations between parties and groups.-create table groups ( +create table groups ( group_id not null constraint groups_group_id_fk references parties (party_id) @@ -141,7 +141,7 @@ member. This is because there is a distinction between direct membership and indirect membership (membership via some component or sub component).-create or replace package membership_rel +create or replace package membership_rel as function new ( @@ -191,7 +191,7 @@ good idea to not give them the option to create a composition relation that would result in a cycle.-create or replace package composition_rel +create or replace package composition_rel as function new ( @@ -212,7 +212,7 @@ show errors -The data model described above does a reasonable job of representing many of the situations one is likely to encounter when modeling organizational structures, but we still need to be able to efficiently answer questions like "what members are in this group and all of its components?", and @@ -232,7 +232,7 @@ container_id. The rel_id might be useful for retrieving or updating standard auditing info for the relation.
-create or replace view group_component_map +create or replace view group_component_map as select group_id, component_id, container_id, rel_id ... @@ -241,15 +241,15 @@ Note that this view will return all membership relations regardless of membership state.-create or replace view group_member_map +create or replace view group_member_map as select group_id, member_id, container_id, rel_id ...The group_approved_member_map is the same as the group_member_map except it only returns entries that relate to approved members.
-create or replace view group_approved_member_map +create or replace view group_approved_member_map as select group_id, member_id, container_id, rel_id ... @@ -258,7 +258,7 @@ direct membership and indirect membership. It simply returns all members of a group including members of components. (It is the transitive closure.)-create or replace view group_distinct_member_map +create or replace view group_distinct_member_map as select group_id, member_id ... @@ -271,20 +271,20 @@ view will have four rows for that party, one for each member, and one from the party to itself.-create or replace view party_member_map +create or replace view party_member_map as select party_id, member_id ...This view is the same as above except that when it expands groups, it only pays attention to approved members.
-create or replace view party_approved_member_map +create or replace view party_approved_member_map as select party_id, member_id ... -As is, the parties data model can represent some fairly sophisticated real +
As is, the parties data model can represent some fairly sophisticated real world situations, and a lot of work has been put into making this efficient, but it is foolish to assume that this data model is sufficient for every application. It therefore seems likely that developers will want to extend Index: openacs-4/packages/acs-core-docs/www/permissions-design.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/permissions-design.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/permissions-design.html 29 Apr 2003 05:58:34 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/permissions-design.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,14 +1,11 @@ -
OpenACS 4 Permissions Design +
OpenACS 4 Permissions Design by John Prevost and Rafael H. Schloming
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -
Tcl in packages/acs-kernel
ER diagram - -
The goal of the Permissions system is to provide generic means to both -programmers and site administrators to designate operations (methods) as -requiring permissions, and then to check, grant, or revoke permissions via a +
Tcl in packages/acs-kernel
The goal of the Permissions system is to provide generic means to both +programmers and site administrators to check, grant, or revoke permissions via a consistent interface. For example, we might decide that the transaction that bans a user from a sub-site is an operation a site administrator is able to assign to a particular user. Or perhaps an application developer might decide @@ -17,13 +14,11 @@ Permissions system will be seeing a lot of use - almost every page will make at least one permissions API call, and some will make several.
For programmers, the Permissions API provides a means to work with access control in a consistent manner. If a programmer's OpenACS package defines new -methods for itself, the Permissions API must provide simple calls to -determine whether the current user is authorized to perform the given method. -In addition, using the Permissions API, queries should easily select only +privilege for itself, the Permissions API must provide simple calls to +determine whether the current user is has been granted that privilege on a given +object. In addition, using the Permissions API, queries should easily select only those package objects on which a user has certain permissions.
For site administrators and other authorized users, the Permissions UI -provides a means to aggregate the primitive operations (methods) made -available by the programmer into logical privileges (like read, write, and -admin) that can be granted and revoked.
In earlier versions of the OpenACS, permissions and access control was handled +provides a means to grant and revoke privileges on objects.
In earlier versions of the OpenACS toolkit, permissions and access control was handled on a module-by-module basis, often even on a page-by-page basis. For example, a typical module might allow any registered user to access its pages read-only, but only allow members of a certain group to make changes. The way @@ -34,118 +29,98 @@ control were many, the two major ones being inconsistency, and repeated/redundant code. Thus the drive in OpenACS 4 to provide a unified, consistent permissions system that both programmers and administrators can -readily use.
The core of the permissions data model is quite simple. Unfortunately, the +readily use.
The core of the permissions data model is quite simple. Unfortunately, the hierarchical nature of default permissions entails quite a number of tree queries which could slow the system down. Since every page will have at least one permissions check, a number of views and auxiliary tables (de-normalizations of the data model) have been created to speed up access queries. As a consequence, speed of updates are decreased and requirements -for additional storage space increase.
As described in section V., the core of the permissions data model is -simple, though a number of views and auxiliary tables exist to ensure -adequate performance. The core model consists of five tables:
- acs_methods +for additional storage space increase.
The core model consists of three tables:
- acs_privileges -
The set of all defined methods.
- acs_privileges +
The set of all defined privileges.
- acs_privilege_hierarchy -
The set of all defined privileges.
- acs_privilege_method_rules - -
A relation describing the set of methods directly -associated with each privilege.
- acs_privilege_hierarchy -
A relation describing which privileges directly -"contain" other privileges.
- acs_permissions +"contain" other privileges.
- acs_permissions
A table with one (party, object, privilege) row for every privilege directly granted on any object in -the system - this is a denormalization of -acs_privilege_method_rules and -acs_privilege_hierarchy
There are also a number of views to make it easier to ask specific +the system. +
There are also a number of views to make it easier to ask specific questions about permissions. For example, a number of the above tables describe "direct" or explicit permissions. Inheritance and default values can, however, introduce permissions which are not directly specified. (For example, read access on a bboard allows read access on all the messages in the bboard.)
The following views provide flattened versions of inherited -information:
- acs_privilege_method_map +information:
- acs_object_grantee_priv_map -
Map of privileges to the methods they contain either directly or because -of another privilege which is included (at any depth).
- acs_object_grantee_priv_map -
Relation on (object, party, privilege) for -privileges from acs_privileges) granted directly on the object, or -on the context of the object (at any depth).
- acs_object_party_privilege_map +privileges from acs_privileges) granted directly on the object, or +on the context of the object (at any depth).
- acs_object_party_privilege_map
Relation on (object, party, privilege) for -privileges directly from acs_object_grantee_priv_map or also because -a party is a member of a group (at any depth).
- acs_object_party_method_map - -
Relation with every (object, party, method) -tuple implied by the above trees.
In general, only acs_object_party_method_map -should be used for queries from other modules. The other views are -intermediate steps in building that query.
The data model also includes two simple PL/SQL procedures -(acs_permission.grant_permission and -acs_permission.revoke_permission) for granting and revoking a +privileges directly from acs_object_grantee_priv_map or also because +a party is a member of a group (at any depth). This view is normally used in an exists +clause to constrain the rows returned by a query to those on which a given party has a given privilege.
The data model also includes two simple PL/SQL procedures +(acs_permission.grant_permission and +acs_permission.revoke_permission) for granting and revoking a specific privilege for a specific user on a specific object.
To sum up, the PL/SQL procedures are meant to be used to grant or revoke -permissions. The five base tables represent the basic data model of the +permissions. The three base tables represent the basic data model of the system, with a set of views provided to convert them into a format suitable for joining to answer specific questions. The exact means by which this transformation takes place should not be depended on, since they may change for efficiency reasons.
The transformations done create a set of default permissions, in which:
parties get the privileges of any groups they are directly or indirectly -a member of
privileges get associated with the methods of any other privileges they -have taken methods from (at any level) (see -acs_privilege_hierarchy)
objects get access control from direct grants, or inherit permissions +a member of
objects get access control from direct grants, or inherit permissions from their context (unless the "don't inherit" flag is -set)
There are two essential areas in which all transactions in the +permissions system fall (a privilege is a an operation like "read", +permissions define which parties have which privileges on which +objects):
Modification of privileges
Modification of permissions
Queries on permissions
"Modification of privileges." This refers to actions that happen mainly at package installation time - a package -will create a number of methods for its own use, then associate them with the -system's standard privileges, or new privileges which the package has -created. The association step might also happen later, if the site-wide -administrator chooses to change permissions policy.
These steps involve directly manipulating the acs_methods, -acs_privileges, and acs_privilege_method_rules tables. A -web page for manipulating these features should be limited to site-wide -administrators.
"Modification of permissions" - involves fairly +may create new privileges and aggregations of privileges. This should be done with care, as +each additional privilege and parent-child privilege relationship added to the system +decreases the performance of the permissions system. Historically, packages have created +their own versions of common privileges like "read" or "write" rather than use the global +permissions created by the kernel. This practice is now discouraged as it adds no +usable functionality, makes the design and implementation of general-purpose permissions UI pages +more difficult, and as mentioned previously negatively impacts performance. +
"Modification of permissions." - involves fairly common operations. Users are typically able to administer permissions for objects they themselves create. The two basic operations here are "grant" and "revoke". Granting permissions is done via -acs_permissions.grant_permission, and revocation via -acs_permissions.revoke_permission. These directly manipulate the -acs_permissions table.
Web pages for making these changes are available to all users, so they +acs_permissions.grant_permission, and revocation via +acs_permissions.revoke_permission. These directly manipulate the +acs_permissions table.
Web pages for making these changes are available to all users, so they should not be in an admin area. In order to grant and revoke permissions on -an object, the user must have the administer_privileges method -permission on that object.
"Queries on permissions" - by far the most +an object, the user must have the admin +privilege on that object.
"Queries on permissions" - by far the most common operation is querying the permissions database. Several kinds of questions are commonly asked: First, and most commonly, "Can this party -perform this method on this object?" Two Tcl functions are provided to +perform this operation on this object?" Two Tcl functions are provided to answer this - one which returns a boolean, the other of which results in an -error page. These tcl functions directly access the -acs_object_party_method_map.
The second most commonly asked question occurs when a list of objects is -being displayed, often in order to provide appropriate UI functionality: -"For this party, what methods are available on these objects?" +error page.
The second most commonly asked question occurs when a list of objects is +being displayed, often in order to provide appropriate UI functionality. Here, the SQL query needs to filter based on whether the party/user can -perform some operation on the object. This is done via a join or sub-select -against acs_object_party_method_map, or by calling the Tcl functions -for appropriate methods.
Finally, when administering the permissions for an object, a web page +perform some operation on the object. This is done by using an exists +clause that returns a value if any row exists in the acs_object_party_privilege_map +view with the given party, object and privilege.
Finally, when administering the permissions for an object, a web page needs to know all permissions directly granted on that object. This is done -by querying against acs_permissions.
The API to the permissions system consists of a few well-known tables, -plus a pair of PL/SQL procedures and a pair of Tcl functions.
Tables
acs_methods, acs_privileges, and -acs_privilege_method_rules manage the set of permissions in the -system. At installation time, a package will add to these three tables to -introduce new permissions into the system.
The main table for queries is acs_object_party_method_map, which -contains (object, party, method) triples for all -allowed operations in the system.
Also of interest for queries is acs_permissions, which lists -directly granted privileges. Neither acs_object_party_method_map -(which is a view) nor acs_permissions should be updated -directly.
PL/SQL Procedures
acs_permissions.grant_permission introduces new permissions for +by querying against acs_permissions.
The API to the permissions system consists of a few well-known tables, +plus a pair of PL/SQL procedures and a pair of Tcl functions.
Tables and views
The main view for queries is acs_object_party_privlege_map, which +contains (object, party, privilege) triples +for all allowed operations in the system.
Also of interest for queries is acs_permissions, which lists +directly granted privileges. Neither acs_object_party_privilege_map +(which is a view) nor acs_permissions should be updated +directly.
PL/[pg]SQL Procedures
acs_permissions.grant_permission introduces new permissions for an object. It should be given an (object, party, privilege) triple, and will always succeed. If the permission is -already in the system, no change occurs. The interface for this procedure -is:
+already in the system, no change occurs.The interface for this procedure is:
procedure grant_permission ( object_id acs_permissions.object_id%TYPE, grantee_id acs_permissions.grantee_id%TYPE, privilege acs_permissions.privilege%TYPE ); -acs_permissions.revoke_permission removes a permission entry +
acs_permissions.revoke_permission removes a permission entry given a triple. It always succeeds--if a permission does not exist, nothing changes. The interface for this procedure is:
procedure revoke_permission ( @@ -154,15 +129,14 @@ privilege acs_permissions.privilege%TYPE );These procedures are defined in -permissions-create.sql
Tcl Procedures
Two tcl procedures provide a simple call for the query, "Can this +permissions-create.sql
Tcl Procedures
Two tcl procedures provide a simple call for the query, "Can this user perform this method on this object?" One returns true or false, the other presents an error page.
To receive a true or false value, Tcl code should call:
-ad_permission_p $object_id $object_type $method -user_id $user_id -If the user_id argument is left out, then the currently logged in -user is checked. To create an error page, Tcl code should call:
-ad_require_permission $object_id $object_type $method -These procedures are defined in acs-permissions-procs.tcl.
All users of the permissions system are the same at the user-interface -level. If you have the administer_privileges method permission on an +permission::permission_p -party_id $party_id -object_id $object_id -privilege $privilege +
To create an error page, Tcl code should call:
+permission::require_permission -party_id $party_id -object_id $object_id -privilege $privilege +These procedures are defined in acs-permissions-procs.tcl.
All users of the permissions system are the same at the user-interface +level. If you have the admin privilege on an object, then you may edit privileges for that object with the UI.
The UI currently provides a list of all granted permissions on the object. If the user wishes to revoke privileges, she may select a set of grants, choose revoke, confirm their deletion, and be returned to the same page after @@ -173,15 +147,15 @@ one object" screen.
If it makes sense, the system will also display a checkbox which the user may select to toggle whether permissions are inherited from the object's context.
There are a number of potential future enhancements for the permissions -UI, outlined below.
The most important future changes to the Permissions system are likely to +UI, outlined below.
The most important future changes to the Permissions system are likely to be in the UI:
There should be a page displaying a list of all objects for which the current user is allowed to administer privileges.
Users should be able to view the permissions on any object, or perhaps on objects which they have the "read_permissions" method. This would allow them to see what grants are affecting their objects through -inheritance.
- System creator -
- System owner +
- System maintainer -
- Documentation author +
- Documentation author -
View comments on this page at openacs.org +John Prevost
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/permissions-requirements.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/permissions-requirements.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/permissions-requirements.html 29 Apr 2003 05:58:34 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/permissions-requirements.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,11 +1,11 @@ -OpenACS 4 Permissions Requirements +
OpenACS 4 Permissions Requirements by John McClary Prevost
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -This document records requirements for the OpenACS 4 Permissions system, a component of the OpenACS 4 Kernel. The Permissions system is meant to unify and -centralize the handling of access and control on a given OpenACS 4 system.
Any multi-user software system must address the general problem of +centralize the handling of access and control on a given OpenACS 4 system.
Any multi-user software system must address the general problem of permissions, or "who can do what, on what." On web services, which typically involve large numbers of users belonging to different groups, permissions handling is a critical need: access to content, services, and @@ -26,14 +26,14 @@ control were many, the two major ones being inconsistency, and repeated/redundant code. Thus the drive in OpenACS 4 to provide a unified, consistent permissions system that both programmers and administrators can -readily use.
The OpenACS 4 Permissions system has two main pieces: first, an API for +readily use.
The OpenACS 4 Permissions system has two main pieces: first, an API for developers to readily handle access control in their applications. The second piece of the system is a UI meant primarily for (subsite) administrators to grant and revoke permissions to system entities under their control.
Consistency is a key characteristic of the Permissions system - both for a common administrative interface, and easily deployed and maintained access control. The system must be flexible enough to support every access model required in OpenACS applications, but not so flexible that pieces will go unused -or fall outside the common administrative interfaces.
Terminology
The primary question an access control system must answer is a three-way +or fall outside the common administrative interfaces.
Terminology
The primary question an access control system must answer is a three-way relation, like that between the parts of most simple sentences. A simple sentence generally has three parts, a subject, an object, and a verb - in the context of OpenACS Permissions, our simple sentence is, "Can this party @@ -50,14 +50,14 @@ that operation.
Examples of the essential question addressed by the Permissions system: Can jane@attacker.com delete the web security bboard? Can the Boston office (a party) within the VirtuaCorp intranet/website create its own news -instance?
10.0 Granularity
The system must support access control down to the level of a single +instance?
10.0 Granularity
The system must support access control down to the level of a single entity (this would imply down to the level of a row in the OpenACS Objects data model).
20.0 Operations
The system itself must be able to answer the essential permissions question as well as several derived questions.
20.10 Basic Access Check
The system must be able to answer the question, "May party P perform operation O on target T?"
20.20 Allowed Parties Check
The system must be able to answer the question, "Which parties may perform operation O on target T?"
20.30 Allowed Operations Check
The system must be able to answer the question, "Which operations may party P perform on target T?"
20.40 Allowed Targets Check
The system must be able to answer the question, "Upon which targets -may party P perform operation O?"
40.0 Scale of Privileges
Privileges must be designed with appropriate scope for a given OpenACS package. Some privileges are of general utility (e.g. "read" and "write"). Others are of more limited use (e.g. "moderate" - applies mainly to a package like bboard, where many users are contributing @@ -83,10 +83,9 @@ (20.40) must be efficient enough for general use, i.e. scalable under fairly heavy website traffic. It can be expected that almost every page will contain at least one basic access check, and most pages will contain an allowed -targets check (20.40).
In particular, constraining a SELECT to return only rows the -current user has access to should not be much slower than the SELECT +targets check (20.40).
In particular, constraining a SELECT to return only rows the +current user has access to should not be much slower than the SELECT on its own.
120.0 Ease of Use
Since most SQL queries will contain an allowed target check in the where clause, whatever mechanism is used to make checks in SQL should be fairly -small and simple.
In particular, constraining a SELECT to return only rows the -current user has access to should not add more than one line to a query.
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 8/17/2000 John Prevost 0.2 Revised, updated with new terminology 8/25/2000 John Prevost 0.3 Edited, reformatted to conform to requirements template, pending -freeze. 8/26/2000 Kai Wu 0.4 Edited for ACS 4 Beta release. 10/03/2000 Kai Wu View comments on this page at openacs.org +small and simple.
Document Revision # Action Taken, Notes When? By Whom? 0.1 Creation 8/17/2000 John Prevost 0.2 Revised, updated with new terminology 8/25/2000 John Prevost 0.3 Edited, reformatted to conform to requirements template, pending +freeze. 8/26/2000 Kai Wu 0.4 Edited for ACS 4 Beta release. 10/03/2000 Kai Wu 0.5 Edited for OpenACS 4.6.3 release. 05/04/2003 Don Baccus View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/permissions-tediously-explained.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/permissions-tediously-explained.html,v diff -u -r1.1.2.9 -r1.1.2.10 --- openacs-4/packages/acs-core-docs/www/permissions-tediously-explained.html 4 May 2003 06:30:03 -0000 1.1.2.9 +++ openacs-4/packages/acs-core-docs/www/permissions-tediously-explained.html 7 May 2003 17:40:59 -0000 1.1.2.10 @@ -1,7 +1,7 @@ -OpenACS 4.x Permissions Tediously Explained +
OpenACS 4.x Permissions Tediously Explained by Vadim Nasardinov. Modified and converted to Docbook XML by Roberto Mello -
+
The general permissions system has a relatively complex data model in OpenACS 4.x. Developers who haven't had the time to learn the internals of the data model may end up writing seemingly correct code that crashes their system in @@ -15,9 +15,9 @@ system internals.
In OpenACS 4.x, most of the interesting tables are expected to extend (subtype) - the acs_objects table, i.e. they are expected to have an integer - primary key column that references the object_id column of - acs_objects. + the acs_objects table, i.e. they are expected to have an integer + primary key column that references the object_id column of + acs_objects.
create table acs_objects ( object_id integer @@ -43,14 +43,14 @@ );
This means that any interesting entity (object) - in the system has an entry in the acs_objects. This + in the system has an entry in the acs_objects. This allows developers to define relationships between any two entities A and B by defining a relationship between their corresponding entries - in the acs_objects table. One of the applications of this + in the acs_objects table. One of the applications of this powerful capability is the general permissions system.
- At the heart of the permission system are two tables: acs_privileges - and acs_permissions. + At the heart of the permission system are two tables: acs_privileges + and acs_permissions.
create table acs_privileges ( privilege varchar2(100) not null @@ -73,20 +73,20 @@ primary key (object_id, grantee_id, privilege) );
- The acs_privileges table stores + The acs_privileges table stores named privileges like read, write, delete, create, and - admin. The acs_permissions + admin. The acs_permissions table stores assertions of the form:
- Who (grantee_id) can do what (privilege) - on which object (object_id). + Who (grantee_id) can do what (privilege) + on which object (object_id).
The naive approach to managing system security would be to require application developers to store permission information explicitly about every object, i.e. if the system has 100,000 and 1,000 users who have the read privilege on all objects, then we would need to store 100,000,000 entries of the form: -
Table�9.1.�
object_id grantee_id privilege object_id_1 user_id_1 'read' object_id_1 user_id_2 'read' ... object_id_1 user_id_n 'read' object_id_2 user_id_1 'read' object_id_2 user_id_2 'read' ... object_id_2 user_id_n 'read' ... ... object_id_m user_id_1 'read' object_id_m user_id_2 'read' ... object_id_m user_id_n 'read' +
Table�9.1.�
object_id grantee_id privilege object_id_1 user_id_1 'read' object_id_1 user_id_2 'read' ... object_id_1 user_id_n 'read' object_id_2 user_id_1 'read' object_id_2 user_id_2 'read' ... object_id_2 user_id_n 'read' ... ... object_id_m user_id_1 'read' object_id_m user_id_2 'read' ... object_id_m user_id_n 'read' Although quite feasible, this approach fails to take advantage of the fact that objects in the system are commonly organized hierarchally, and permissions usually follow the hierarchical structure, so that if user @@ -98,42 +98,42 @@ necessity to explicitly maintain security information for every single object. There are three kinds of hierarchies involved. These are discussed in the following sections. -
Suppose objects A, B, ..., and F form the following hierarchy. -
Table�9.2.�
A - object_id=10 +
Table�9.2.�
A + object_id=10
B - object_id=20 + object_id=20
C - object_id=30 + object_id=30
D - object_id=40 + object_id=40
E - object_id=50 + object_id=50
F - object_id=60 + object_id=60
- This can be represented in the + This can be represented in the acs_objects table by the following entries: -
+
The first entry tells us that object 20 is the descendant of object 10, and the third entry shows that object 40 is the descendant of object 20. By running a CONNECT BY query, we can compute that object 40 is the second-generation descendant of object 10. With this in mind, if we want to record the fact that user Joe has the read privilege on objects A, ..., F, we only need to record one entry in the - acs_permissions table. -
+ acs_permissions table. +
The fact that Joe can also read B, C, ..., and F can be derived by ascertaining that these objects are children of A by traversing the context hierarchy. As it turns out, hierarchical queries are expensive. As Rafael Schloming put it so aptly, Oracle can't deal with hierarchies for shit.
One way to solve this problem is to cache a flattened view of the context tree like so: -
+
Note that the number of entries in the flattened view grows exponentially with respect to the depth of the context tree. For instance, if you have a fully populated binary tree with a depth of n, then the number of entries @@ -143,7 +143,7 @@ Despite its potentially great storage costs, maintaining a flattened representation of the context tree is exactly what OpenACS 4.x does. The flattened context tree is stored in the - acs_object_context_index table. + acs_object_context_index table.
create table acs_object_context_index ( object_id @@ -154,7 +154,7 @@ constraint acs_obj_context_idx_anc_id_fk references acs_objects(object_id), n_generations integer not null - constraint acs_obj_context_idx_n_gen_ck check (n_generations >= 0), + constraint acs_obj_context_idx_n_gen_ck check (n_generations >= 0), constraint acs_object_context_index_pk primary key (object_id, ancestor_id) ) organization index; @@ -168,8 +168,8 @@ has, and exponentially with respect to the depth of the context tree.- The acs_object_context_index is kept in sync with the - acs_objects + The acs_object_context_index is kept in sync with the + acs_objects table by triggers like this:
create or replace trigger acs_objects_context_id_in_tr @@ -199,40 +199,40 @@ end if; end;- One final note about + One final note about acs_objects. By setting - an object's security_inherit_p column to 'f', you can stop permissions + an object's security_inherit_p column to 'f', you can stop permissions from cascading down the context tree. In the following example, Joe does not have the read permissions on C and F. -
Table�9.6.�
+Table�9.6.�
A
-object_id=10
+object_id=10
readable�by�Joe
������
B
-object_id=20
+object_id=20
readable�by�Joe
��������������
C
-object_id=30
+object_id=30
security_inherit_p�=�'f'
not�readable�by�Joe
������
D
-object_id=40
+object_id=40
������
E
-object_id=50
+object_id=50
������
F
-object_id=60
+object_id=60
security_inherit_p�=�'f'
not�readable�by�Joe
- ������Privileges are also organized hierarchically. In addition to the five main system privileges defined in the ACS Kernel data model, application developers may define their own. For instance, the Bboard package defines the following privileges: -
Table�9.7.�
privilege create_category create_forum create_message delete_category delete_forum delete_message moderate_forum read_category read_forum read_message write_category write_forum write_message +
Table�9.7.�
privilege create_category create_forum create_message delete_category delete_forum delete_message moderate_forum read_category read_forum read_message write_category write_forum write_message By defining parent-child relationship between privileges, the OpenACS data model makes it easier for developers to manage permissions. Instead of granting a user explicit read, write, delete, @@ -241,9 +241,9 @@ privilege to which the first four privileges are tied. To give a more detailed example, the Bboard privileges are structured as follows. -
Table�9.8.�
admin create delete read write moderate forum create category create forum create message delete category delete forum delete message read category read forum read message write category write forum write message +
Table�9.8.�
admin create delete read write moderate forum create category create forum create message delete category delete forum delete message read category read forum read message write category write forum write message The parent-child relationship between privileges is represented in - the acs_privilege_hierarchy table: + the acs_privilege_hierarchy table:
create table acs_privilege_hierarchy ( privilege @@ -284,10 +284,10 @@ reasonably small, there is no pressing need to cache the flattened ansector-descendant view of the privilege hierarchy in a specially maintained table like it is done in the case of the context hierarchy. -
Now for the third hierarchy playing a promiment role in the permission system. The party data model is set up as follows. -
+create table parties ( party_id not null @@ -326,9 +326,9 @@ group_name varchar2(100) not null );
- Recall that the grantee_id column of the + Recall that the grantee_id column of the acs_permissions table references - parties.party_id. + parties.party_id. This means that you can grant a privilege on an object to a party, person, user, or group. Groups represent aggregations of parties. The most common scenario that you are likely to encounter is a group that is a collection of users, although you could also @@ -339,7 +339,7 @@ a group named Pranksters, you can assign membership to Pete, Poly, and Penelope. The fact that these users are members of the Pranksters group will be recorded in the - membership_rels and acs_rels tables: + membership_rels and acs_rels tables:
create table acs_rels ( rel_id @@ -369,9 +369,9 @@ check (member_state in ('approved', 'banned', 'rejected', 'deleted')) );
- The acs_rels + The acs_rels table entries would look like so: -
Table�9.10.�
rel_type object_one object_two + Table�9.10.�
rel_type object_one object_two membership_rel Pranksters @@ -395,8 +395,8 @@ of Pranksters. We say that the Pranksters group is composed of groups Merry Pranksters and Sad Pranksters. This - information is stored in the acs_rels - and composition_rels tables. + information is stored in the acs_rels + and composition_rels tables. create table composition_rels ( rel_id @@ -405,8 +405,8 @@ );
The relevant entries in the - acs_rels look like so. -
Table�9.11.�
rel_type object_one object_two + acs_rels look like so. + Table�9.11.�
rel_type object_one object_two composition_rel Pranksters @@ -472,17 +472,17 @@ primary key (member_id, group_id, rel_id) ) organization index; - The group_component_index table stores a flattened representation of the - group composition hierarchy that is maintained in sync with the acs_rels - and composition_rels tables through triggers. + The group_component_index table stores a flattened representation of the + group composition hierarchy that is maintained in sync with the acs_rels + and composition_rels tables through triggers.
- As far as the group_member_index table goes, I am not sure I understand its + As far as the group_member_index table goes, I am not sure I understand its purpose. It maintains group-member relationships that are resolved with respect to group composition. Note that information stored in - group_member_index can be trivially derived by joining - membership_rels, - acs_rels, - and group_component_index. Here + group_member_index can be trivially derived by joining + membership_rels, + acs_rels, + and group_component_index. Here is a view that does it. (This view is not part of the OpenACS Kernel data model.)
create or replace view group_member_view @@ -507,8 +507,8 @@ mr.rel_id = r.rel_id and r.object_id_one = gci.component_id;- A heuristic way to verify that group_member_view is essentially identical - to group_member_index is to compute the + A heuristic way to verify that group_member_view is essentially identical + to group_member_index is to compute the symmetric difference between the two:
select @@ -531,12 +531,12 @@The query returns no rows. The important point is, if we have a flattened view of the composition hierarchy -- like one provided - by the group_component_index table -- + by the group_component_index table -- membership relationship resolution can be computed trivially with no hierarchical queries involved. There is no need to keep the view in a denormalized table, unless doing so results in substantial performance gains. -
- Security information is queried by calling the acs_permission.permission_p +
+ Security information is queried by calling the acs_permission.permission_p function in OpenACS 4.x.
create or replace package body acs_permission @@ -563,13 +563,13 @@ end acs_permission;The function simply queries - acs_object_party_privilege_map, + acs_object_party_privilege_map, which is a humongous view that joins three flattened hierarchies: the context tree, the privilege hierarchy, the party composition (and membership) hierarchy. As such, it contains an extremely large number of rows. About the only kind of query you can run against it is the one - performed by the acs_permission.permission_p + performed by the acs_permission.permission_p function. Anything other than that would take forever to finish or would ultimately result in an Oracle error.
@@ -593,9 +593,9 @@ for rec in cur loop acs_permission.revoke_permission ( - object_id => rec.object_id, - grantee_id => rec.party_id, - privilege => 'foo_create' + object_id => rec.object_id, + grantee_id => rec.party_id, + privilege => 'foo_create' ); end loop; @@ -605,7 +605,7 @@ end; /
- The acs_permission.revoke_permission function merely runs a + The acs_permission.revoke_permission function merely runs a delete statement like so:
delete from @@ -615,9 +615,9 @@ and grantee_id = revoke_permission.grantee_id and privilege = revoke_permission.privilege;- Note that in the above example, acs_permissions had only + Note that in the above example, acs_permissions had only one entry that needed to be deleted: -
Table�9.12.�
object_id grantee_id privilege + The above script would never get around to deleting this entry because it had to loop through a gazillion rows in the humongous - acs_object_party_privilege_map view. -
create or replace view acs_object_party_privilege_map as select Index: openacs-4/packages/acs-core-docs/www/permissions.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/permissions.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/permissions.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/permissions.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,12 +1,12 @@ -Groups, Context, Permissions By Pete Su
+Groups, Context, Permissions By Pete Su
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -The OpenACS 4.6.3 Permissions system allows developers and administrators to set access control policies at the object level, that is, any application or system object represented by a row in the -acs_objects table can be access-controlled via a simple +acs_objects table can be access-controlled via a simple PL/SQL or Tcl interface. The permissions system manages a data model that then allows scripts to check permissions using another simple API call. @@ -21,7 +21,7 @@ together into larger security domains. The rest of this document will talk about each of these parts, and how they fit together with the permissions system. -
In OpenACS 3.x, the groups system allowed developers and administrators to define simple groupings of users. Each group had a human readable name and unique ID, and there was a single mapping table that mapped users @@ -51,7 +51,7 @@ OpenACS 4.6.3 solves both of these modeling problems by introducing a new abstraction called a party. Parties have a recursive definition, and we can illustrate how it works with the following -simplified data model. First, we define the parties +simplified data model. First, we define the parties table, where each party has an email address and a URL for contact information.
@@ -79,9 +79,9 @@ )-The users table is also defined in this data model as a -subtype of person. It contains many of the basic columns -that the old OpenACS 3.x users table contained. +The users table is also defined in this data model as a +subtype of person. It contains many of the basic columns +that the old OpenACS 3.x users table contained.
Finally, we define two relations, one for group membership and one for group composition. The composition relation allows us @@ -104,7 +104,7 @@ The full details of the groups data model is beyond the scope of this tutorial - I've just given you what you need to understand how permissions work. For further detail, you can look at Parties in OpenACS 4 or OpenACS 4 Groups Design. -
NOTE: Much more detailed information about the permissions system and how to use it is available in the OpenACS Permissions Tediously Explained document. @@ -147,7 +147,7 @@
To give a user permission to perform a particular operation on a particular object you call -acs_permission.grant_permission like this: +acs_permission.grant_permission like this:
@@ -164,12 +164,12 @@ to every object individually: in many cases, we'd prefer controlling permissions to large groups of objects in the site, all at once. We use contexts to achieve this goal. -In OpenACS 4.6.3, an object context is a generalization of the scoping mechanism introduced in OpenACS 3.x. "Scoping" and "scope" are terms best explained by example: consider some hypothetical rows in the -address_book table: -
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ... +address_book table: +
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ... The first row represents an entry in User 123's personal address book, the second row represents an entry in User Group 456's shared address book, and the third row represents an entry in the site's public @@ -185,21 +185,21 @@ another object that represents the security domain to which the object belongs. By convention, if an object A doesn't have any permissions explicitly attached to it, then the system will look at the -context_id column in acs_objects and check +context_id column in acs_objects and check the context object there for permissions. Two things control the scope of this search: the structure of the context hierarchy itself, and the -value of the security_inherit_p flag in each object. If -this flag is set to 't', then the automatic search +value of the security_inherit_p flag in each object. If +this flag is set to 't', then the automatic search through the context happens, otherwise it does not. You might set this -field to 'f' if you want to override the default +field to 'f' if you want to override the default permissions in a subtree of some context.
A good example of how to use this hierarchy is in the bboard application. With only row-level permissions it is not obvious how to reasonably initialize the access control list when creating a message. At best, we have to explicitly grant various read and write privileges whenever we create a message, which is tedious. In OpenACS 4.6.3, a reasonable thing to do is to create an object representing a forum, -and point the context_id field of a new message at the +and point the context_id field of a new message at the forum. Then, suppose we grant every user in the system read-access to this forum. By default, they will automatically have read-access to the new message we just inserted, since the system automatically @@ -214,23 +214,23 @@
A few things to note here. First, the top two contexts in the picture are "magic" in some sense because they are created by default by OpenACS -for a specific purpose. The object default_context +for a specific purpose. The object default_context represents the root of the context hierarchy for the entire site. All permission searches walk up the tree to this point and then stop. If you grant permissions on this object, then by default those permissions will hold for every object in the system, regardless of which subsite they happen to live in. The object -security_context_root has a slightly different role. If +security_context_root has a slightly different role. If some object has no permissions attached to it, and its value for -security_inherit_p is 'f', or -context_id is null, then we use this context by default. -
At this point, you should either go and download the Notes example code from the package repository, or check it out of the ArsDigita CVS repository and add it to your server. The package is called "notes". To check it out from CVS, read the these instructions on how to use anonymous checkouts and then -checkout the module acs-packages/notes: +checkout the module acs-packages/notes:
@@ -240,7 +240,7 @@After you have downloaded the package, look at the -index.tcl page in the www directory. You can also +index.tcl page in the www directory. You can also look at the code in your browser. The code should look something like this:
@@ -289,8 +289,8 @@This example shows both the Tcl and PL/SQL APIs for checking -permissions. The Tcl proc ad_permission_p and the PL/SQL -function acs_permission.permission_p both return a flag +permissions. The Tcl proc ad_permission_p and the PL/SQL +function acs_permission.permission_p both return a flag indicating whether the current user has permission to perform the given action. By default, the Tcl procedure extracts the user_id out of the request environment, while the SQL procedure takes it as an @@ -306,9 +306,9 @@ see notes that we are allowed to see.
Next, look at the index.adp. It is pretty complicated. -The main part of this page uses a multiple template +The main part of this page uses a multiple template tag. If you want to experiment, you can replace the main body of the -multiple tag with this: +multiple tag with this:
<multiple name=notes> @@ -331,7 +331,7 @@This displays the title of the note as either a link or plain text depending on whether or not we have write privileges on the object. -The if tag is something that the OpenACS 4.6.3 template system +The if tag is something that the OpenACS 4.6.3 template system defines for you to support conditional presentation. The templates developer guide provides more information about this.
If you study the rest of the system, you will also notice that the @@ -344,7 +344,7 @@ implement a user interface that allowed the user to explicitly attach permissions to notes that she wanted to make public or whatever. But that's beyond the scope of this example. -
OpenACS 4.6.3 defines three separate mechanisms for specifying access control in applications. The Groups data model allows you to define hierarchical organizations of users and groups of users. The Permissions Index: openacs-4/packages/acs-core-docs/www/postgres.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/postgres.html,v diff -u -r1.6.2.8 -r1.6.2.9 --- openacs-4/packages/acs-core-docs/www/postgres.html 4 May 2003 06:30:03 -0000 1.6.2.8 +++ openacs-4/packages/acs-core-docs/www/postgres.html 7 May 2003 17:40:59 -0000 1.6.2.9 @@ -1,109 +1,109 @@ -
Install PostGreSQL 7.2.4 +
Install PostGreSQL 7.2.4 by Vinod Kurup
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.Skip this section if you will run only Oracle.
OpenACS 4.6.3 will run with PostGreSQL 7.2.x or 7.3.2. It has not been fully tested with 7.3.2; 7.2.4 is the recommended version of PostgreSQL to use.
This page assumes you have downloaded postgresql to -/tmp/postgresql-7.2.4.tar.gz. If not, +/tmp/postgresql-7.2.4.tar.gz. If not, get it. -
Unpack PostGreSQL.
[root@yourserver root]# cd /usr/local/src -[root@yourserver src]# tar xzf /tmp/postgresql-7.2.4.tar.gz +
Unpack PostGreSQL.
[root@yourserver root]# cd /usr/local/src +[root@yourserver src]# tar xzf /tmp/postgresql-7.2.4.tar.gz [root@yourserver src]# -cd /usr/local/src -tar xzf /tmp/postgresql-7.2.4.tar.gzCreate the Postgres user.� +
cd /usr/local/src +tar xzf /tmp/postgresql-7.2.4.tar.gz
Create the Postgres user.� Create a user and group (if you haven't done so before) for PostgreSQL. This is the account that PostgreSQL will run as since it will not run as root. Since nobody will log in directly as that user, we'll leave the password blank. -
[root@yourserver src]# groupadd web -[root@yourserver src]# useradd -g web -d /usr/local/pgsql postgres -[root@yourserver src]# mkdir -p /usr/local/pgsql -[root@yourserver src]# chown -R postgres.web /usr/local/pgsql /usr/local/src/postgresql-7.2.4 -[root@yourserver src]# chmod 750 /usr/local/pgsql +[root@yourserver src]# groupadd web +[root@yourserver src]# useradd -g web -d /usr/local/pgsql postgres +[root@yourserver src]# mkdir -p /usr/local/pgsql +[root@yourserver src]# chown -R postgres.web /usr/local/pgsql /usr/local/src/postgresql-7.2.4 +[root@yourserver src]# chmod 750 /usr/local/pgsql [root@yourserver src]# -groupadd web +groupadd web useradd -g web -d /usr/local/pgsql postgres mkdir -p /usr/local/pgsql chown -R postgres.web /usr/local/pgsql /usr/local/src/postgresql-7.2.4 -chmod 750 /usr/local/pgsql
Set up postgres's environment variables. They are +chmod 750 /usr/local/pgsql
Set up postgres's environment variables. They are necessary for the executable to find its supporting libraries. For convenience, we'll simply append the necessary - lines to the postgres shell config file.
[root@yourserver src]# echo "export LD_LIBRARY_PATH=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pgsql/lib" >> ~postgres/.bashrc -[root@yourserver src]# echo "export PATH=$PATH:/usr/local/pgsql/bin" >> ~postgres/.bashrc -echo "export LD_LIBRARY_PATH=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pgsql/lib" >> ~postgres/.bashrc -echo "export PATH=$PATH:/usr/local/pgsql/bin" >> ~postgres/.bashrcTest this by logging in as - postgres and checking the - paths; you should see /usr/local/pgsql/bin
[root@yourserver src]# su - postgres -[postgres@yourserver pgsql]$ env | grep PATH + lines to the postgres shell config file.[root@yourserver src]# echo "export LD_LIBRARY_PATH=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pgsql/lib" >> ~postgres/.bashrc +[root@yourserver src]# echo "export PATH=$PATH:/usr/local/pgsql/bin" >> ~postgres/.bashrc +echo "export LD_LIBRARY_PATH=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pgsql/lib" >> ~postgres/.bashrc +echo "export PATH=$PATH:/usr/local/pgsql/bin" >> ~postgres/.bashrc
Test this by logging in as + postgres and checking the + paths; you should see /usr/local/pgsql/bin
[root@yourserver src]# su - postgres +[postgres@yourserver pgsql]$ env | grep PATH LD_LIBRARY_PATH=LD_LIBRARY_PATH=:/usr/local/pgsql/lib PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin/X11:/usr/X11R6/bin:/root/bin:/usr/local/pgsql/bin:/usr/local/pgsql/bin -[postgres@yourserver pgsql]$ exit +[postgres@yourserver pgsql]$ exitCompile and install PostgreSQL.� - Change to the postgres user and run ./configure to set the compilation options automatically. This is the point at which you can + Change to the postgres user and run ./configure to set the compilation options automatically. This is the point at which you can configure PostgreSQL in various ways. For example, if you want to enable - Unicode support, add the flags --enable-locale and --enable-multibyte. If you want to see what the other possibilities are, run ./configure --help. -
[root@yourserver src]# su - postgres -[postgres@yourserver pgsql]$ cd /usr/local/src/postgresql-7.2.4 -[postgres@yourserver postgresql-7.2.4]$ ./configure + Unicode support, add the flags --enable-locale and --enable-multibyte. If you want to see what the other possibilities are, run ./configure --help. +[root@yourserver src]# su - postgres +[postgres@yourserver pgsql]$ cd /usr/local/src/postgresql-7.2.4 +[postgres@yourserver postgresql-7.2.4]$ ./configure creating cache ./config.cache checking host system type... i686-pc-linux-gnu (many lines omitted> linking ./src/makefiles/Makefile.linux to src/Makefile.port linking ./src/backend/port/tas/dummy.s to src/backend/port/tas.s -[postgres@yourserver postgresql-7.2.4]$ make all +[postgres@yourserver postgresql-7.2.4]$ make all make -C doc all make[1]: Entering directory `/usr/local/src/postgresql-7.2.4/doc' (many lines omitted) make[1]: Leaving directory `/usr/local/src/postgresql-7.2.4/src' All of PostgreSQL successfully made. Ready to install. -[postgres@yourserver postgresql-7.2.4]$ make install +[postgres@yourserver postgresql-7.2.4]$ make install make -C doc install make[1]: Entering directory `/usr/local/src/postgresql-7.2.4/doc' (many lines omitted) Thank you for choosing PostgreSQL, the most advanced open source database engine. -su - postgres +su - postgres cd /usr/local/src/postgresql-7.2.4 ./configure make all -make install
Start PostgreSQL.� - The initdb command initializes the - database. pg_ctl is used to start up +make install
Start PostgreSQL.� + The initdb command initializes the + database. pg_ctl is used to start up PostgreSQL. -
[postgres@yourserver tsearch]$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data +[postgres@yourserver tsearch]$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data The files belonging to this database system will be owned by user "postgres". This user must also own the server process. (17 lines omitted) or /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start -[postgres@yourserver tsearch]$ /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l /usr/local/pgsql/data/server.log start +[postgres@yourserver tsearch]$ /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l /usr/local/pgsql/data/server.log start postmaster successfully started [postgres@yourserver tsearch]$ -/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data -/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l /usr/local/pgsql/data/server.log start+
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data +/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l /usr/local/pgsql/data/server.log start
PostgreSQL errors will be logged in - /usr/local/pgsql/data/server.log + /usr/local/pgsql/data/server.log
Set up plpgsql and allow your user to have access. Plpgsql is a PL/SQL-like language. We add it to template1, which is the template from which all new databases are created. We can verify that it was created - with the createlang command in list mode.
[postgres@yourserver pgsql]$ createlang plpgsql template1 -[postgres@yourserver pgsql]$ createlang -l template1 + with the createlang command in list mode.[postgres@yourserver pgsql]$ createlang plpgsql template1 +[postgres@yourserver pgsql]$ createlang -l template1 Procedural languages Name | Trusted? ---------+---------- plpgsql | t (1 row) [postgres@yourserver pgsql]$ -createlang plpgsql template1 -createlang -l template1Test PostgreSQL. Create a database and try some simple commands. The output should be as shown. -
[postgres@yourserver pgsql]$ createdb mytestdb +createlang plpgsql template1 +createlang -l template1
Test PostgreSQL. Create a database and try some simple commands. The output should be as shown. +
[postgres@yourserver pgsql]$ createdb mytestdb CREATE DATABASE -[postgres@yourserver pgsql]$ psql mytestdb +[postgres@yourserver pgsql]$ psql mytestdb Welcome to psql, the PostgreSQL interactive terminal. Type: \copyright for distribution terms @@ -112,24 +112,24 @@ \g or terminate with semicolon to execute query \q to quit -mytestdb=# select current_timestamp; +mytestdb=# select current_timestamp; timestamptz ------------------------------- 2003-03-07 22:18:29.185413-08 (1 row) -mytestdb=# create function test1() returns integer as 'begin return 1; end;' language 'plpgsql'; +mytestdb=# create function test1() returns integer as 'begin return 1; end;' language 'plpgsql'; CREATE -mytestdb=# select test1(); +mytestdb=# select test1(); test1 ------- 1 (1 row) -mytestdb=# \q -[postgres@yourserver pgsql]$ dropdb mytestdb +mytestdb=# \q +[postgres@yourserver pgsql]$ dropdb mytestdb DROP DATABASE -[postgres@yourserver pgsql]$ exit +[postgres@yourserver pgsql]$ exit logout [root@yourserver src]#Set PostgreSQL to start on boot. First, we copy the @@ -140,39 +140,39 @@ changes runlevels, postgresql goes to the appropriate state. Red Hat and Debian and SuSE each work a little differently so three sets of instructions are provided. -
Red Hat:
[root@yourserver src]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql -[root@yourserver src]# chown root.root /etc/rc.d/init.d/postgresql -[root@yourserver src]# chmod 755 /etc/rc.d/init.d/postgresql +
Red Hat:
[root@yourserver src]# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql +[root@yourserver src]# chown root.root /etc/rc.d/init.d/postgresql +[root@yourserver src]# chmod 755 /etc/rc.d/init.d/postgresql [root@yourserver src]# -cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql +cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql chown root.root /etc/rc.d/init.d/postgresql -chmod 755 /etc/rc.d/init.d/postgresql
Test the script.
[root@yourserver root]# service postgresql stop +chmod 755 /etc/rc.d/init.d/postgresqlTest the script.
[root@yourserver root]# service postgresql stop Stopping PostgreSQL: ok [root@yourserver root]#If PostgreSQL successfully stopped, then use the following command to make sure that the script is run appropriately at boot and shutdown. And turn it back on because we'll use it later. -
[root@yourserver root]# chkconfig --add postgresql -[root@yourserver root]# chkconfig --list postgresql +[root@yourserver root]# chkconfig --add postgresql +[root@yourserver root]# chkconfig --list postgresql postgresql 0:off 1:off 2:on 3:on 4:on 5:on 6:off -[root@yourserver root]# service postgresql start +[root@yourserver root]# service postgresql start Starting PostgreSQL: ok [root@yourserver root]# -chkconfig --add postgresql +chkconfig --add postgresql chkconfig --list postgresql -service postgresql start
Debian:
root:~# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql -root:~# chown root.root /etc/init.d/postgresql -root:~# chmod 700 /etc/init.d/postgresql -root:~#+service postgresql startDebian:
root:~# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql +root:~# chown root.root /etc/init.d/postgresql +root:~# chmod 700 /etc/init.d/postgresql +root:~#cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql chown root.root /etc/init.d/postgresql -chmod 700 /etc/init.d/postgresql
Test the script
root:~# /etc/init.d/postgresql stop +chmod 700 /etc/init.d/postgresqlTest the script
root:~# /etc/init.d/postgresql stop Stopping PostgreSQL: ok root:~#If PostgreSQL successfully stopped, then use the following command to make sure that the script is run appropriately at boot and shutdown.
-root:~# update-rc.d postgresql defaults +root:~# update-rc.d postgresql defaults Adding system startup for /etc/init.d/postgresql ... /etc/rc0.d/K20postgresql -> ../init.d/postgresql /etc/rc1.d/K20postgresql -> ../init.d/postgresql @@ -181,50 +181,50 @@ /etc/rc3.d/S20postgresql -> ../init.d/postgresql /etc/rc4.d/S20postgresql -> ../init.d/postgresql /etc/rc5.d/S20postgresql -> ../init.d/postgresql -root:~# /etc/init.d/postgresql start +root:~# /etc/init.d/postgresql start Starting PostgreSQL: ok root:~#SuSE:
Note
I have received reports that SuSE 8.0 is different from previous versions. Instead of installing the boot scripts in - /etc/rc.d/init.d/, they should - be placed in /etc/init.d/. If + /etc/rc.d/init.d/, they should + be placed in /etc/init.d/. If you're using SuSE 8.0, delete the - rc.d/ part in each of the + rc.d/ part in each of the following commands. -
root:~# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/rc.d/init.d/postgresql -root:~# chown root.root /etc/rc.d/init.d/postgresql -root:~# chmod 700 /etc/rc.d/init.d/postgresql+
root:~# cp /tmp/openacs-4.6.3/packages/acs-core-docs/www/files/postgresql.txt /etc/rc.d/init.d/postgresql +root:~# chown root.root /etc/rc.d/init.d/postgresql +root:~# chmod 700 /etc/rc.d/init.d/postgresqlTest the script. -
root:~# /etc/rc.d/init.d/postgresql stop +root:~# /etc/rc.d/init.d/postgresql stop Stopping PostgreSQL: okIf PostgreSQL successfully stopped, then use the following command to make sure that the script is run appropriately at boot and shutdown. -
root:~# cd /etc/rc.d/init.d -root:/etc/rc.d/init.d# ln -s /etc/rc.d/init.d/postgresql K20postgresql -root:/etc/rc.d/init.d# ln -s /etc/rc.d/init.d/postgresql S20postgresql -root:/etc/rc.d/init.d# cp K20postgresql rc2.d -root:/etc/rc.d/init.d# cp S20postgresql rc2.d -root:/etc/rc.d/init.d# cp K20postgresql rc3.d -root:/etc/rc.d/init.d# cp S20postgresql rc3.d -root:/etc/rc.d/init.d# cp K20postgresql rc4.d -root:/etc/rc.d/init.d# cp S20postgresql rc4.d -root:/etc/rc.d/init.d# cp K20postgresql rc5.d -root:/etc/rc.d/init.d# cp S20postgresql rc5.d -root:/etc/rc.d/init.d# rm K20postgresql -root:/etc/rc.d/init.d# rm S20postgresql +root:~# cd /etc/rc.d/init.d +root:/etc/rc.d/init.d# ln -s /etc/rc.d/init.d/postgresql K20postgresql +root:/etc/rc.d/init.d# ln -s /etc/rc.d/init.d/postgresql S20postgresql +root:/etc/rc.d/init.d# cp K20postgresql rc2.d +root:/etc/rc.d/init.d# cp S20postgresql rc2.d +root:/etc/rc.d/init.d# cp K20postgresql rc3.d +root:/etc/rc.d/init.d# cp S20postgresql rc3.d +root:/etc/rc.d/init.d# cp K20postgresql rc4.d +root:/etc/rc.d/init.d# cp S20postgresql rc4.d +root:/etc/rc.d/init.d# cp K20postgresql rc5.d +root:/etc/rc.d/init.d# cp S20postgresql rc5.d +root:/etc/rc.d/init.d# rm K20postgresql +root:/etc/rc.d/init.d# rm S20postgresql root:/etc/rc.d/init.d#Test configuration. -
root:/etc/rc.d/init.d # cd -root:~ # /etc/rc.d/init.d/rc2.d/S20postgresql start +root:/etc/rc.d/init.d # cd +root:~ # /etc/rc.d/init.d/rc2.d/S20postgresql start Starting PostgreSQL: ok root:~ #@@ -236,11 +236,11 @@ little. This usually isn't a problem as Red Hat defaults to runlevel 3)
Tune postgres. OPTIONAL.�The default values for PostGreSQL are very conservative; we can safely change some of them and improve performance.
Change the kernel parameter for maximum shared memory - segment size to 128Mb:
[root@yourserver root]# echo 134217728 >/proc/sys/kernel/shmmax + segment size to 128Mb:[root@yourserver root]# echo 134217728 >/proc/sys/kernel/shmmax [root@yourserver root]#Make that change permanent by editing - emacs /etc/sysctl.conf to + emacs /etc/sysctl.conf to add these lines at the end:
# increase shared memory limit for postgres -kernel.shmmax = 134217728Edit the PostGreSQL config file, /usr/local/pgsql/data/postgresql.conf to use more memory. These values should improve performance in most cases. (More information)
# Shared Memory Size +kernel.shmmax = 134217728Edit the PostGreSQL config file, /usr/local/pgsql/data/postgresql.conf to use more memory. These values should improve performance in most cases. (More information)
# Shared Memory Size # shared_buffers = 15200 # 2*max_connections, min 16 @@ -253,7 +253,7 @@ # wal_files = 3 # range 0-64 checkpoint_segments = 3 # in logfile segments (16MB each), min 1 -Restart postgres (service postgres restart) so that the changes take effect.
+
Restart postgres (service postgres restart) so that the changes take effect.
Official PostgreSQL Docs Index: openacs-4/packages/acs-core-docs/www/programming-with-aolserver.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/programming-with-aolserver.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/programming-with-aolserver.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/programming-with-aolserver.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,68 +1,68 @@ -
Programming with AOLserver +
Programming with AOLserver by Michael Yoon, Jon Salz and Lars Pind.
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -When using AOLserver, remember that there are effectively two types of global namespace, not one:
Server-global: As you'd expect, there is only one server-global namespace per server, and variables set within it can be accessed by any Tcl code running subsequently, in any of the server's -threads. To set/get server-global variables, use AOLserver 3's nsv API -(which supersedes ns_share from the pre-3.0 API). +threads. To set/get server-global variables, use AOLserver 3's nsv API +(which supersedes ns_share from the pre-3.0 API).
Script-global: Each Tcl script (ADP, Tcl page, registered proc, filter, etc.) executing within an AOLserver thread has its own global namespace. Any variable set in the top level of a script is, by definition, script-global, meaning that it is accessible only by subsequent code in the same script and only for the duration of the current script execution.
-The Tcl built-in command global +The Tcl built-in command global accesses script-global, not server-global, variables from within a procedure. This distinction is important to understand in order to use -global correctly when programming AOLserver. +global correctly when programming AOLserver.
Also, AOLserver purges all script-global variables in a thread (i.e., Tcl interpreter) between HTTP requests. If it didn't, that would affect (and complicate) our use of script-global variables dramatically, which would then be better described as thread-global variables. Given AOLserver's behaviour, however, "script-global" is a more -appropriate term.
-ns_schedule_proc and ad_schedule_proc each take a --thread flag to cause a scheduled procedure to run +appropriate term.
+ns_schedule_proc and ad_schedule_proc each take a +-thread flag to cause a scheduled procedure to run asychronously, in its own thread. It almost always seems like a good idea to specify this switch, but there's a problem. -
It turns out that whenever a task scheduled with ns_schedule_proc --thread or ad_schedule_proc -thread t is run, AOLserver +
It turns out that whenever a task scheduled with ns_schedule_proc +-thread or ad_schedule_proc -thread t is run, AOLserver creates a brand new thread and a brand new interpreter, and reinitializes the procedure table (essentially, loads all procedures that were created during server initialization into the new interpreter). This happens every time the task is executed - and it is a very expensive process that should not be taken lightly!
The moral: if you have a lightweight scheduled procedure -which runs frequently, don't use the -thread +which runs frequently, don't use the -thread switch.
Note also that thread is initialized with a copy of what was installed during server startup, so if the procedure table have changed since startup (e.g. using the APM watch facility), that will not be reflected in the scheduled -thread.
+The return command in Tcl returns control to the caller procedure. This definition allows nested procedures to work properly. However, this -definition also means that nested procedures cannot use return to +definition also means that nested procedures cannot use return to end an entire thread. This situation is most common in exception conditions that can be triggered from inside a procedure e.g., a permission denied exception. At this point, the procedure that detects invalid permission wants to write an error message to the user, and completely abort execution of the -caller thread. return doesn't work, because the procedure may be -nested several levels deep. We therefore use ad_script_abort -to abort the remainder of the thread. Note that using return instead -of ad_script_abort may raise some security issues: an attacker could +caller thread. return doesn't work, because the procedure may be +nested several levels deep. We therefore use ad_script_abort +to abort the remainder of the thread. Note that using return instead +of ad_script_abort may raise some security issues: an attacker could call a page that performed some DML statement, pass in some arguments, and get a permission denied error -- but the DML statement would still be -executed because the thread was not stopped. Note that return -code +executed because the thread was not stopped. Note that return -code return can be used in circumstances where the procedure will only be called from two levels deep. -
-Many functions have a single return value. For instance, empty_string_p +
+Many functions have a single return value. For instance, empty_string_p returns a number: 1 or 0. Other functions need to return a composite value. For instance, consider a function that looks up a user's name and email address, given an ID. One way to implement this is to return a three-element @@ -77,7 +77,7 @@
AOLserver/Tcl generally has three mechanisms that we like, for returning more than one value from a function. When to use which depends on the circumstances.
Using Arrays and Pass-By-Value
-The one we generally prefer is returning an array +The one we generally prefer is returning an array get-formatted list. It has all the nice properties of pass-by-value, and it uses Tcl arrays, which have good native support.
@@ -95,7 +95,7 @@ doc_body_append "$user_info(namelink) ($user_info(emaillink))"You could also have done this by using an array internally and using -array get: +array get:
ad_proc ad_get_user_info { user_id } { @@ -119,7 +119,7 @@ milisecond. The time depends almost completely on the number of entries, and almost not at all on the size of the entries.You implement pass-by-reference in Tcl by taking the name of an array -as an argument and upvar it. +as an argument and upvar it.
ad_proc ad_get_user_info { @@ -141,17 +141,17 @@We prefer pass-by-value over pass-by-reference. Pass-by-reference makes the code harder to read and debug, because changing a value in one place has side effects in other places. Especially if have a chain of -upvars through several layers of the call stack, you'll have -a hard time debugging.
Multisets: Using ns_sets and Pass-By-Reference
+upvars through several layers of the call stack, you'll have +a hard time debugging.
Multisets: Using ns_sets and Pass-By-Reference
An array is a type of set, which means you can't have multiple entries with the same key. Data structures that can have multiple entries for the same key are known as a multiset or bag.
If your data can have multiple entries with the same key, -you should use the AOLserver built-in +you should use the AOLserver built-in ns_set. You can also do a case-insensitive lookup on an -ns_set, something you can't easily do on an array. This is +ns_set, something you can't easily do on an array. This is especially useful for things like HTTP headers, which happen to have these -exact properties.
You always use pass-by-reference with ns_sets, since they +exact properties.
You always use pass-by-reference with ns_sets, since they don't have any built-in way of generating and reconstructing themselves from a string representation. Instead, you pass the handle to the set.
@@ -172,11 +172,11 @@ doc_body_append "[ns_set get $user_info namelink] ([ns_set get $user_info emaillink])"-We don't recommend ns_set as a general mechanism for passing +We don't recommend ns_set as a general mechanism for passing sets (as opposed to multisets) of data. Not only do they inherently use pass-by-reference, which we dis-like, they're also somewhat clumsy to use, since Tcl doesn't have built-in syntactic support for them. -
Consider for example a loop over the entries in a ns_set as +
Consider for example a loop over the entries in a ns_set as compared to an array:
# ns_set variant @@ -207,9 +207,9 @@ ]-ns_sets are designed to be lightweight, so memory consumption -should not be a problem. However, when using ns_set get to +ns_sets are designed to be lightweight, so memory consumption +should not be a problem. However, when using ns_set get to perform lookup by name, they perform a linear lookup, whereas arrays use a -hash table, so ns_sets are slower than arrays when the number of +hash table, so ns_sets are slower than arrays when the number of entries is large.
($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/psgml-mode.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/psgml-mode.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/psgml-mode.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/psgml-mode.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,43 +1,43 @@ -Using PSGML mode in Emacs +
Using PSGML mode in Emacs By David Lutterkort
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -PSGML Mode is a mode for editing, umm, SGML and XML documents in emacs. It can parse a DTD and help you insert the right tags in the right place, knows about tags' attributes and can tell you in which contexts a tag can be used. If you give it the right DTD, that is. But even without a DTD, -it can save you some typing since pressing C-c/ will close an open -tag automatically.
Most newer emacsen come with PSGML mode preinstalled. You can find out -whether your emacs has it with the locate-library command. In Emacs, -type M-x locate-library and enter psgml. Emacs will tell +it can save you some typing since pressing C-c/ will close an open +tag automatically.
Most newer emacsen come with PSGML mode preinstalled. You can find out +whether your emacs has it with the locate-library command. In Emacs, +type M-x locate-library and enter psgml. Emacs will tell you if it found it or not.
If you don't have PSGML preinstalled in your Emacs, there are two things you can do:
On Linux: Get the psgml rpm from RedHat's docbook-tools and install it as usual.
On other systems: Get the tarball from the PSGML Website. -Unpack it and follow the install instructions.
The easiest way to teach PSGML mode about a DTD is by adding it to your +own CATALOG. Here is an example of how you can set that up for the Docbook XML DTD.
Get the Docbook XML DTD zip archive from docbook.org
Go somewhere in your working directory and do
mkdir -p dtd/docbook-xml cd dtd/docbook-xml unzip -a <docbook XML DTD zip archive> -Create a file with the name CATALOG in the dtd +
Create a file with the name CATALOG in the dtd directory and put the line
CATALOG "docbook-xml/docbook.cat"-in it. By maintaining your own CATALOG, it is easy to add more +in it. By maintaining your own CATALOG, it is easy to add more DTD's without changing your emacs settings. (How about that HTML 4.01 DTD you always wanted to get from W3C ? The DTD is in the zip archives and tarballs available on the site.
That's it. Now you are ready to tell emacs all about PSGML mode and -that funky CATALOG
If you installed PSGML mode in a non-standard location, e.g., somewhere in -your home directory, you need to add this to the load-path by adding -this line to your .emacs file:
+that funky CATALOGIf you installed PSGML mode in a non-standard location, e.g., somewhere in +your home directory, you need to add this to the load-path by adding +this line to your .emacs file:
(add-to-list 'load-path "/some/dir/that/contains/psgml.elc") -To let PSGML mode find your CATALOG and to enable PSGML mode for -all your editing, add these lines to your .emacs:
+To let PSGML mode find your CATALOG and to enable PSGML mode for +all your editing, add these lines to your .emacs:
(require 'psgml) (add-to-list 'auto-mode-alist '("\\.html" . sgml-mode)) @@ -48,7 +48,7 @@ (add-to-list 'sgml-catalog-files "/path/to/your/dtd/CATALOG")If you want font-locking and indentation, you can also add these lines -into the .emacs file:
+into the .emacs file:(setq sgml-markup-faces '((start-tag . font-lock-function-name-face) (end-tag . font-lock-function-name-face) (comment . font-lock-comment-face) @@ -64,8 +64,8 @@ (define-key sgml-mode-map "\C-c\C-x\C-i" 'sgml-general-dtd-info) (define-key sgml-mode-map "\C-c\C-x\C-t" 'sgml-describe-entity)))) -All SGML and XML documents that should conform to a DTD have to declare a -doctype. For the docbook XML, all your .xml files whould start with +
All SGML and XML documents that should conform to a DTD have to declare a +doctype. For the docbook XML, all your .xml files whould start with the line
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "docbookx.dtd"> @@ -79,9 +79,9 @@ -->Which says that the parent of this document can be found in the file -top.xml, that the element in the parent that will enclose the -current document is a book and that the current file's topmost -element is a sect1.
Of course, you should read the emacs texinfo pages that come with PSGML -mode from start to finish. Barring that, here are some handy commands:
Key Command C-c C-e Insert an element. Uses completion and only lets you insert elements that -are valid C-c C-a Edit attributes of enclosing element. C-c C-x C-i Show information about the document's DTD. C-c C-x C-e Describe element. Shows for one element which elements can be parents, -what its contents can be and lists its attributes. View comments on this page at openacs.org +top.xml, that the element in the parent that will enclose the +current document is a book and that the current file's topmost +element is a sect1.Of course, you should read the emacs texinfo pages that come with PSGML +mode from start to finish. Barring that, here are some handy commands:
Key Command C-c C-e Insert an element. Uses completion and only lets you insert elements that +are valid C-c C-a Edit attributes of enclosing element. C-c C-x C-i Show information about the document's DTD. C-c C-x C-e Describe element. Shows for one element which elements can be parents, +what its contents can be and lists its attributes. View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/release-notes.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/release-notes.html,v diff -u -r1.9.2.7 -r1.9.2.8 --- openacs-4/packages/acs-core-docs/www/release-notes.html 19 Apr 2003 20:39:33 -0000 1.9.2.7 +++ openacs-4/packages/acs-core-docs/www/release-notes.html 7 May 2003 17:40:59 -0000 1.9.2.8 @@ -1,10 +1,10 @@ -OpenACS 4.6.2 Release Notes +
OpenACS 4.6.3 Release Notes by Don Baccus
- OpenACS docs are written by the named authors, but may be edited + OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.- This is a final release of OpenACS 4.6.2. This release has been subjected + This is a final release of OpenACS 4.6.3. This release has been subjected to an organized test effort, but please bear in mind that we are still in the process of developing testing tools, methodology, and scripts.
@@ -30,19 +30,19 @@ problems.
You may want to begin by reading our installation documentation for - Chapter�3. Note that the Windows documentation is - not current for OpenACS 4.6.2, but an alternative is to use John + Chapter�3, Installing on Unix/Linux. Note that the Windows documentation is + not current for OpenACS 4.6.3, but an alternative is to use John Sequeira's Oasis VM project.
After installation, the full documentation set can be found by visiting - http://[your-host]/doc. Not all pieces are updated for OpenACS 4.6.2 at + http://[your-host]/doc. Not all pieces are updated for OpenACS 4.6.3 at this moment. -
+
If you're using Oracle 8.1.6 or 8.1.7 Enterprise Edition you may want to uncomment the SQL that causes InterMedia to keep online searching online while indexing. The feature doesn't exist in Standard Edition - and OpenACS 4.6.2 now defaults to being loadable in SE. Just grep for + and OpenACS 4.6.3 now defaults to being loadable in SE. Just grep for 'sync' to find the code.
Also be sure to read the documentation in the Site Wide Search @@ -56,12 +56,12 @@ installation documentation in the section, 4. As with the Oracle version, there are steps you must take manually in order to get this feature working. -
dotLRN 1.0 is an e-learning solution from MIT based on OpenACS 4.6.2 The dotLRN 1.0 testing effort was organized by Bart Teeuwisse and made use of the OpenACS Bug Tracker and OpenACS test servers hosted by Collaboraid. -
($Id$)View comments on this page at openacs.org +($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/request-processor.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/request-processor.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/request-processor.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/request-processor.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,21 +1,21 @@ -The Request Processor +
The Request Processor By Pete Su
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -This document is a brief introduction to the OpenACS 4.6.3 Request Processor; more details can be found in the OpenACS 4 Request Processor Design. Here we cover the high level concepts behind the system, and implications and usage for the application developer. -
In older versions of the OpenACS, the mapping between URLs and pages was simple. AOLserver, the usual webserver for the OpenACS, would find the appropriate file by appending the server's page-root to the path in the URL and returning that file to the user. For example, a user's request for a URL like "http://foo-service.com/bar.html" would cause the server to look in the filesystem for -/web/foo-service/www/bar.html, and return that file. +/web/foo-service/www/bar.html, and return that file. This was simple enough, but OpenACS did not provide a clean centralized mechanism for the following requirements of larger web services: @@ -27,30 +27,30 @@ To achieve this functionality above in OpenACS 3.x, developers used an ad -hoc combination of AOLserver filters, the ns_perm call, +hoc combination of AOLserver filters, the ns_perm call, special purpose code in pages, and other procedures. In OpenACS 4.6.3, the Request Processor, along with the OpenACS Package Manager, centralizes and unifies this functionality, making it more transparent and readily available to developers. -
The 4.6.3 Request Processor is a global filter and set of Tcl procs that respond to every incoming URL reaching the server. The following diagram summarizes the stages of the request processor assuming a URL -request like http://someserver.com/notes/somepage.adp. +request like http://someserver.com/notes/somepage.adp. -
[D]+
[D]
- Stage 1: Search Site Map
The first thing the RP does is to map the given URL to the appropriate physical directory in the filesystem, from which to serve content. We do this by searching the site map data model (touched on in the Packages, and further -discussed in the section called “Writing OpenACS 4.6.3 Application Pages”). This data model maps URLs to objects representing +discussed in Section�, “Writing OpenACS 4.6.3 Application Pages”). This data model maps URLs to objects representing content, and these objects are typically package instances.
After looking up the appropriate object, the RP stores the URL, the ID of the object it found, and the package and package instance the object belongs to into the environment of the connection. This -environment can be queried using the ad_conn procedure, +environment can be queried using the ad_conn procedure, which is described in detail in OpenACS 4 Request Processor Design. The page development tutorial shows you how to use this interface to make your pages aware of which instance was requested. @@ -74,15 +74,15 @@ Finally, the Request Processor finds the file we intend to serve, searching the filesystem to locate the actual file that corresponds to an abstract URL. It searches for files with predefined "magic" -extensions, i.e. files that end with: .html, -.tcl and .adp. +extensions, i.e. files that end with: .html, +.tcl and .adp.
If the RP can't find any matching files with the expected extensions, -it will look for virtual-url-handler files, or .vuh -files. A .vuh file will be executed as if it were a Tcl +it will look for virtual-url-handler files, or .vuh +files. A .vuh file will be executed as if it were a Tcl file, but with the tail end of the URL removed. This allows the code -in the .vuh file to act like a registered procedure for -an entire subtree of the URL namespace. Thus a .vuh file +in the .vuh file to act like a registered procedure for +an entire subtree of the URL namespace. Thus a .vuh file can be thought of as a replacement for filters and registered procs, except that they integrate cleanly and correctly with the RP's URL mapping mechanisms. The details of how to use these files are @@ -91,64 +91,64 @@ Once the appropriate file is found, it is either served directly if it's static content, or sent to the template system or the standard Tcl interpreter if it's a dynamic page. -
Once the flow of control reaches a dynamic page, the Request Processor has populated the environment of the request with several pieces of useful information. The RP's environment is accessible through the -ad_conn interface, and the following calls should be +ad_conn interface, and the following calls should be useful to you when developing dynamic pages: -
- [ad_conn user_id] +
- [ad_conn user_id]
The ID of the user associated with this request. By convention this is zero if there is no user. -
- [ad_conn session_id] +
- [ad_conn session_id]
The ID of the session associated with this request. -
- [ad_conn url] +
- [ad_conn url]
The URL associated with the request. -
- [ad_conn urlv] +
- [ad_conn urlv]
The URL associated with the request, represented as a list instead of a single string. -
- [ad_conn file] +
- [ad_conn file]
The actual local filesystem path of the file that is being served. -
- [ad_conn object_url] +
- [ad_conn object_url]
If the URL refers to a site map object, this is the URL to the root of the tree where the object is mounted. -
- [ad_conn package_url] +
- [ad_conn package_url]
If the URL refers to a package instance, this is the URL to the root of the tree where the package is mounted. -
- [ad_conn extra_url] +
- [ad_conn extra_url]
If we found the URL in the site map, this is the tail of the URL following the part that matched a site map entry. -
- [ad_conn object_id] +
- [ad_conn object_id]
If the URL refers to a site map object, this is the ID of that object. -
- [ad_conn package_id] +
- [ad_conn package_id]
If the URL refers to a package instance, this is the ID of that package instance. -
- [ad_conn package_key] +
- [ad_conn package_key]
If the URL refers to a package instance, this is the unique key name of the package. -
- [ad_conn path_info] +
- [ad_conn path_info]
In a .vuh file, path_info is the trailing part of the URL not matched Index: openacs-4/packages/acs-core-docs/www/requirements-template.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/requirements-template.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/requirements-template.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/requirements-template.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,8 +1,8 @@ -
System/Application Requirements Template By You
+System/Application Requirements Template By You
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Briefly explain to the reader what this document is for, whether it records the requirements for a new system, a client application, a toolkit subsystem, etc. Remember your audience: fellow programmers, @@ -11,35 +11,35 @@ everywhere, write clearly and precisely; for requirements documentation, write at a level that any intelligent layperson can understand. -
Very broadly, describe how the system meets a need of a business, group, the OpenACS as a whole, etc. Make sure that technical and non-technical readers alike would understand what the system would do and why it's useful. Whenever applicable, you should explicitly state what the business value of the system is. -
Discuss the high-level breakdown of the components that make up the system. You can go by functional areas, by the main transactions the system allows, etc.
You should also state the context and dependencies of the system here, e.g. if it's an application-level package for OpenACS 4, briefly describe how it uses kernel services, like permissions or subsites. -
Determine the types or classes of users who would use the system, and what their experience would be like at a high-level. Sketch what their experience would be like and what actions they would take, and how the system would support them. -
Describe other systems or services that are comparable to what you're building. If applicable, say why your implementation will be superior, where it will match the competition, and where/why it will lack existing best-of-breed capabilities. This section is also in the Design doc, so write about it where you deem most appropriate. -
Include all pertinent links to supporting and related material, - such as:
System/Package "coversheet" - where all documentation for this software is linked off of
Design document
Developer's guide
User's guide
Other-cool-system-related-to-this-one document
Test plan
Competitive system(s)
Include all pertinent links to supporting and related material, + such as:
System/Package "coversheet" - where all documentation for this software is linked off of
Design document
Developer's guide
User's guide
Other-cool-system-related-to-this-one document
Test plan
Competitive system(s)
The main course of the document, requirements. Break up the requirements sections (A, B, C, etc.) as needed. Within each section, create a list denominated with unique identifiers that reflect any @@ -74,11 +74,11 @@ suited to handle combinations of inputs.
Flowcharts - easy to draw and understand, suited for event and decision driven systems. UML is the industry standard here.
Entity-Relationship diagrams - a necessary part of Design documents, sometimes a high-level ER diagram is useful for - requirements as well.
Although in theory coding comes after design, which comes after requirements, we do not, and perhaps should not, always follow such a rigid process (a.k.a. the waterfall lifecyle). Often, there is a pre-existing system or prototype first, and thus you may want to write some thoughts on implementation, for aiding and guiding yourself or other programmers. -
View comments on this page at openacs.org +View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/rp-design.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/rp-design.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/rp-design.html 29 Apr 2003 05:58:34 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/rp-design.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,19 +1,19 @@ -OpenACS 4 Request Processor Design +
OpenACS 4 Request Processor Design by Rafael H. Schloming
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -The request processor is the set of procs that responds to every HTTP request made to the OpenACS. The request processor must authenticate the connecting user, and make sure that he is authorized to perform the given request. If these steps succeed, then the request processor must locate the file that is associated with the specified URL, and serve the content it -provides to the browser.
+provides to the browser.
pageroot -- Any directory that contains scripts and/or static files intended to be served in response to HTTP requests. A typical OpenACS installation is required to serve files from multiple pageroots.
global pageroot @@ -31,7 +31,7 @@ that has been translated into a file system path (probably by prepending the appropriate pageroot), but still doesn't have any extension and so does not directly correspond to a file in the filesystem.
concrete file or concrete path -- A file -or path that actually references something in the filesystem.
Package Lookup
One of the first things the request processor must do is to determine which package instance a given request references, and based on this information, which pageroot to use when searching for a file to serve. During this process the request processor divides the URL into two pieces. The first @@ -75,7 +75,7 @@ special distinction is required between sitewide procs and package specific procs when using this facility. It is also much less prone to overlap and confusion than the use of registered procs, especially in an environment with -many packages installed.
The request processor manages the mappings from URL patterns to package +many packages installed.
The request processor manages the mappings from URL patterns to package instances with the site_nodes data model. Every row in the site_nodes table represents a fully qualified URL. A package can be mounted on any node in this data model. When the request processor performs a URL lookup, it @@ -88,14 +88,14 @@ performed by starting with the full request URI and successively stripping off the rightmost path components until a match is reached. This way the time required to lookup a URL is proportional to the length of the URL, not to the -number of entries in the mapping.
The request environment is managed by the procedure +number of entries in the mapping.
The request environment is managed by the procedure ad_conn. Variables can be set and retrieved through use of the ad_conn procedure. The following variables are available for public use. If the ad_conn procedure doesn't recognize a variable being passed to it for a lookup, it tries to get a value using ns_conn. This guarantees that -ad_conn subsumes the functionality of ns_conn.
Request processor [ad_conn urlv] A list containing each element of the URL [ad_conn url] The URL associated with the request. [ad_conn file] The filepath including filename of the file being served [ad_conn request] The number of requests since the server was last started [ad_conn start_clicks] The system time when the RP starts handling the request � Session System Variables: set in -sec_handler, check security with ad_validate_security_info [ad_conn session_id] The unique session_id coming from the sequence -sec_id_seq [ad_conn user_id] User_id of a person if the person is logged in. Otherwise, it is -blank [ad_conn sec_validated] This becomes "secure" when the connection uses SSL � Database API [ad_conn db,handles] What are the list of handles available to AOL? [ad_conn db,n_handles_used] How many database handles are currently used? [ad_conn db,last_used] Which database handle did we use last? [ad_conn db,transaction_level,$db] Specifies what transaction level we are in [ad_conn db,db_abort_p,$dbh] Whether the transaction is aborted � APM � Packages [ad_conn package_id] The package_id of the package associated with the URL. [ad_conn package_url] The URL on which the package is mounted. � Miscellaneous [ad_conn system_p] If true then the request has been made to one of the special directories +ad_conn subsumes the functionality of ns_conn.
Request processor [ad_conn urlv] A list containing each element of the URL [ad_conn url] The URL associated with the request. [ad_conn file] The filepath including filename of the file being served [ad_conn request] The number of requests since the server was last started [ad_conn start_clicks] The system time when the RP starts handling the request � Session System Variables: set in +sec_handler, check security with ad_validate_security_info [ad_conn session_id] The unique session_id coming from the sequence +sec_id_seq [ad_conn user_id] User_id of a person if the person is logged in. Otherwise, it is +blank [ad_conn sec_validated] This becomes "secure" when the connection uses SSL � Database API [ad_conn db,handles] What are the list of handles available to AOL? [ad_conn db,n_handles_used] How many database handles are currently used? [ad_conn db,last_used] Which database handle did we use last? [ad_conn db,transaction_level,$db] Specifies what transaction level we are in [ad_conn db,db_abort_p,$dbh] Whether the transaction is aborted � APM � Packages [ad_conn package_id] The package_id of the package associated with the URL. [ad_conn package_url] The URL on which the package is mounted. � Miscellaneous [ad_conn system_p] If true then the request has been made to one of the special directories specified in the config file (somewhere), and no authentication or -authorization has been performed. � Documentation [ad_conn api_page_documentation_mode_p] �
Prev Home Next OpenACS 4 Request Processor Requirements Up Documenting Tcl Files: Page Contracts and Libraries
docs@openacs.orgView comments on this page at openacs.org +authorization has been performed.� Documentation [ad_conn api_page_documentation_mode_p] �
Prev Home Next OpenACS 4 Request Processor Requirements Up Documenting Tcl Files: Page Contracts and Libraries
docs@openacs.orgView comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/rp-requirements.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/rp-requirements.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/rp-requirements.html 29 Apr 2003 05:58:34 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/rp-requirements.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,15 +1,15 @@ -OpenACS 4 Request Processor Requirements +
OpenACS 4 Request Processor Requirements by Rafael H. Schloming
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -The following is a requirements document for the OpenACS 4.0 request processor. The major enhancements in the 4.0 version include a more sophisticated directory mapping system that allows package pageroots to be mounted at arbitrary urls, and tighter integration with the database to allow -for flexible user controlled url structures, and subsites.
Most web servers are designed to serve pages from exactly one static +for flexible user controlled url structures, and subsites.
Most web servers are designed to serve pages from exactly one static pageroot. This restriction can become cumbersome when trying to build a web -toolkit full of reusable and reconfigurable components.
The request processor's functionality can be split into two main +toolkit full of reusable and reconfigurable components.
The request processor's functionality can be split into two main pieces.
Set up the environment in which a server side script expects to run. This includes things like:
Initialize common variables associated with a request.
Authenticate the connecting party.
Check that the connecting party is authorized to proceed with the request.
Invoke any filters associated with the request URI.
Determine to which entity the request URI maps, and deliver the content @@ -19,7 +19,7 @@ for the connecting party. Eventually this may also require determining the capabilities of the connecting browser and choosing the most appropriate form for the delivered content.
It is essential that any errors that occur during the above steps be -reported to developers in an easily decipherable manner.
10.0 Multiple Pageroots
10.10 Pageroots may be combined into one URL space.
10.20 Pageroots may be mounted at more than one location in the URL +reported to developers in an easily decipherable manner.
10.0 Multiple Pageroots
10.10 Pageroots may be combined into one URL space.
10.20 Pageroots may be mounted at more than one location in the URL space.
20.0 Application Context
20.10 The request processor must be able to determine a primary context or state associated with a pageroot based on it's location within the URL space.
30.0 Authentication
30.10 The request processor must be able to verify that the connecting Index: openacs-4/packages/acs-core-docs/www/security-design.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/security-design.html,v diff -u -r1.7.2.7 -r1.7.2.8 --- openacs-4/packages/acs-core-docs/www/security-design.html 29 Apr 2003 05:58:34 -0000 1.7.2.7 +++ openacs-4/packages/acs-core-docs/www/security-design.html 7 May 2003 17:40:59 -0000 1.7.2.8 @@ -1,10 +1,10 @@ -
OpenACS 4 Security Design +
OpenACS 4 Security Design by Richard Li, Archit Shah
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -This document explains security model design for OpenACS 4. The security system with the OpenACS core must authenticate users in both secure and insecure environments. In addition, this subsystem provides sessions on top of the @@ -20,15 +20,15 @@
SSL with server authentication: SSL v3
SSL provides the client with a guarantee that the server is actually the server it is advertised as being. It also provides a secure transport. -
A session is defined as a series of clicks in which no two clicks are separated by more than some constant. This constant is the parameter SessionTimeout. Using the expiration time on the signatures of the signed cookies, we can verify when the cookie was issued and determine if two requests are part of the same session. It is important to note that the expiration time set in the cookie protocol is not trusted. Only the time inserted by the signed cookie mechanism is trusted. -
Two levels of access can be granted: insecure and secure. This grant lasts for the remainder of the particular session. Secure authentication tokens are only issued over secured connections. @@ -42,41 +42,41 @@ password can be sniffed from the system, after which the sniffer can apply for a secure authentication token. However, the basic architecture here lays the foundation for a secure system and can be easily adapted to a more secure -authentication system by forcing all logins to occur over HTTPS.
The authentication system issues up to four signed cookies (see below), +authentication system by forcing all logins to occur over HTTPS.
The authentication system issues up to four signed cookies (see below), with each cookie serving a different purpose. These cookies are:
name value max-age secure? ad_session_id session_id,user_id SessionTimeout no ad_user_login user_id Infinity no ad_user_login_secure user_id,random Infinity yes ad_secure_token session_id,user_id,random SessionLifetime yes
ad_session_id
reissued on any hit separated by more than SessionRenew seconds from the previous hit that received a cookie
is valid only for SessionTimeout seconds
is the canonical source for the session ID in ad_conn
ad_user_login
is used for permanent logins
ad_user_login_secure
is used for permanent secure logins
contains random garbage (ns_time) to prevent attack against the secure hash
ad_secure_token
is a session-level cookie from the browser's standpoint
its signature expires in SessionLifetime seconds
contains random garbage (ns_time) to prevent attack against the secure -hash
user_id is extraneous
The Tcl function (sec_handler) is called by the request processor to authenticate the user. It first checks the -ad_session_id cookie. If there is no valid session in progress, -a new session is created with sec_setup_session. If the user -has permanent login cookies (ad_user_login and -ad_user_login_secure), then they are looked at to determine what +ad_session_id cookie. If there is no valid session in progress, +a new session is created with sec_setup_session. If the user +has permanent login cookies (ad_user_login and +ad_user_login_secure), then they are looked at to determine what user the session should be authorized as. Which cookie is examined is determined by whether or not the request is on a secure connection. If neither cookie is present, then a session is created without any -authentication. If the ad_session_id cookie is valid, the -user_id and session_id are pulled from it and put into ad_conn.
Secure connections are authenticated slightly differently. The function -ad_secure_conn_p is used to determine whether or not the URL +authentication. If the ad_session_id cookie is valid, the +user_id and session_id are pulled from it and put into ad_conn.
Secure connections are authenticated slightly differently. The function +ad_secure_conn_p is used to determine whether or not the URL being accessed is requires a secure login. The function simply checks if the location begins with "https". (This is safe because the location is -set during the server initialization.)
If secure authentication is required, the ad_secure_token +set during the server initialization.)
If secure authentication is required, the ad_secure_token cookie is checked to make sure its data matches the data stored in -ad_session_id. This is true for all pages except those that are +ad_session_id. This is true for all pages except those that are part of the login process. On these pages, the user can not yet have received -the appropriate ad_secure_token cookie, so no check against it +the appropriate ad_secure_token cookie, so no check against it is performed. The set of pages that skip that processing are determined by -determined by ad_login_page. Since the -ad_secure_token cookie is a session cookie, it is deleted by the +determined by ad_login_page. Since the +ad_secure_token cookie is a session cookie, it is deleted by the browser when the browser exits. Since an attacker could conceivably store the secure cookie in a replay attack (since expiration date is not validated), the data in the secure cookie is never used to set any data in ad_conn; user_id and session_id is set from the ad_session_id cookie.
It is important to note that the integrity of secure authentication rests -on the two Tcl function ad_secure_conn_p and -ad_login_page. If ad_secure_conn_p is false, secure -authentication is not required. If ad_login_page is false, -secure authentication is not required.
The Tcl function ad_user_login does two things. First it +on the two Tcl function ad_secure_conn_p and +ad_login_page. If ad_secure_conn_p is false, secure +authentication is not required. If ad_login_page is false, +secure authentication is not required.
The Tcl function ad_user_login does two things. First it performs the appropriate manipulation of the permanent login cookies, and then it updates the current session to reflect the new user_id. The manipulation of the permanent login cookies is based on 3 factors:
previous login: other user, same user
permanent: was a permanent login requested?
secure: is this a secure connection?
@@ -86,42 +86,42 @@ immediately
nothing: if the cookie is present, it remains
The current state of the permanent login cookies is not taken into account when determining the appropriate action. -
previous login state permanent login requested secure connection action on insecure action on secure other y y set set same y y set set other y n set delete same y n set nothing same n y nothing delete other n y delete delete other n n delete delete same n n delete delete ad_user_login -callssec_setup_session which actually calls -sec_generate_session_id_cookie to generate the +
previous login state permanent login requested secure connection action on insecure action on secure other y y set set same y y set set other y n set delete same y n set nothing same n y nothing delete other n y delete delete other n n delete delete same n n delete delete ad_user_login +callssec_setup_session which actually calls +sec_generate_session_id_cookie to generate the new cookie with refer to the appropriate user_id. If the connection is secure -the ad_secure_token cookie is generated by a -call to sec_generate_secure_token_cookie. This +the ad_secure_token cookie is generated by a +call to sec_generate_secure_token_cookie. This function is only called from -sec_setup_session. Only -sec_handler and -sec_setup_session call -sec_generate_session_id_cookie. +sec_setup_session. Only +sec_handler and +sec_setup_session call +sec_generate_session_id_cookie. -
ad_user_logout logs the user out by deleting all 4 cookies -that are used by the authentication system.
The creation and setup of sessions is handled in -sec_setup_session, which is called either to -create a new session from sec_handler or from -ad_user_login when there is a change in +
ad_user_logout logs the user out by deleting all 4 cookies +that are used by the authentication system.
The creation and setup of sessions is handled in +sec_setup_session, which is called either to +create a new session from sec_handler or from +ad_user_login when there is a change in authorization level. The session management code must do two things: insure that session-level data does not float between users, and update the users table -which has columns for n_sessions, -last_visit, and -second_to_last_visit.
If there is no session already setup on this hit, a new session is -created. This happens when sec_setup_session is -called from sec_handler. If the login is from a +which has columns for n_sessions, +last_visit, and +second_to_last_visit.
If there is no session already setup on this hit, a new session is +created. This happens when sec_setup_session is +called from sec_handler. If the login is from a user to another user, a new session is created, otherwise, the current session is continued, simply with a higher authorization state. This allows for data associated with a session to be carried over when a user logs in.
The users table is updated by -sec_update_user_session_info which is called +sec_update_user_session_info which is called when an existing session is assigned a non-zero user_id, or when a session is -created with a non-zero user_id.
ad_user_login assumes a password check has already been performed (this will change in the future). The actual check is done by -ad_check_password. The database stores a salt and a hash of the +ad_check_password. The database stores a salt and a hash of the password concatenated with the salt. Updating the password -(ad_change_password) simply requires getting a new salt +(ad_change_password) simply requires getting a new salt (ns_time) concatenating and rehashing. Both the salt and the hashed password -field are updated.
A session is labeled by a session_id sequence. Creating a session merely +field are updated.
A session is labeled by a session_id sequence. Creating a session merely requires incrementing the session_id sequence. We do two things to improve the performance of this process. First, sequence values are precomputed and cached in the Oracle SGA. In addition, sequence values are incremented by 100 with each @@ -130,41 +130,41 @@ command per thread. This minimizes lock contention for the session ID sequence and also minimizes the number of DB requests, since each thread can allocate 100 sessions before requiring another DB hit. This cache works by keeping two -counters: tcl_max_value and -tcl_current_sequence_id. When -tcl_current_sequence_id is greater than -tcl_max_value a new value is requested from the -db and tcl_max_value is incremented by +counters: tcl_max_value and +tcl_current_sequence_id. When +tcl_current_sequence_id is greater than +tcl_max_value a new value is requested from the +db and tcl_max_value is incremented by 100. This is done on a per-thread basis so that no locking is required.
In addition, two procedures are dynamically generated at startup in -security-init.tcl. These two procedures use -ad_parameter to obtain the constant value of a given parameter; +security-init.tcl. These two procedures use +ad_parameter to obtain the constant value of a given parameter; these values are used to dynamically generate a procedure that returns a constant. This approach avoids (relatively) expensive calls to -ad_parameter in sec_handler. The impact of this +ad_parameter in sec_handler. The impact of this approach is that these parameters cannot be dynamically changed at runtime -and require a server restart.
Session properties are stored in a single table that maps session IDs to named session properties and values. This table is periodically purged. For maximum performance, the table is created with nologging turned on and new extents are allocated in 50MB increments to reduce fragmentation. This table -is swept periodically by sec_sweep_session which removes +is swept periodically by sec_sweep_session which removes sessions whose first hit was more than SessionLifetime seconds (1 week by default) ago. Session properties are removed through that same process with cascading delete. -
Session properties can be set as secure. In this case, -ad_set_client_property will fail if the connection is not -secure. ad_get_client_property will behave as if the property -had not been set if the property was not set securely.
Session properties can be set as secure. In this case, +ad_set_client_property will fail if the connection is not +secure. ad_get_client_property will behave as if the property +had not been set if the property was not set securely.
Signed cookies are implemented using the generic secure digital signature mechanism. This mechanism guarantees that the user can not tamper with (or construct a value of his choice) without detection. In addition, it provides the optional facility of timing out the signature so it is valid for only a certain period of time. This works by simply including an expiration time as part of the value that is signed. -
The signature produced by ad_sign is the Tcl list of -token_id,expire_time,hash, where hash = +
The signature produced by ad_sign is the Tcl list of +token_id,expire_time,hash, where hash = SHA1(value,token_id,expire_time,secret_token). The secret_token is a forty character randomly generated string that is never sent to any user agent. The scheme consists of one table:
@@ -176,7 +176,7 @@ token_timestamp sysdate ); -ad_verify_signature takes a value and a signature and +
ad_verify_signature takes a value and a signature and verifies that the signature was generated using that value. It works simply by taking the token_id and expire_time from the signature, and regenerating the hash using the supplied value and the secret_token corresponding to the @@ -196,13 +196,13 @@ mandates that the user-agent use "secure means" to contact the server when transmitting the cookie. If a secure cookie is returned to the client over https, then the cookie will never be transmitted over insecure -means.
Performance is a key goal of this implementation of signed cookies. To +means.
Performance is a key goal of this implementation of signed cookies. To maximize performance, we will use the following architecture. At the lowest -level, we will use the secret_tokens table as the canonical set +level, we will use the secret_tokens table as the canonical set of secret tokens. This table is necessary for multiple servers to maintain the same set of secret tokens. At server startup, a random subset of these secret tokens will be loaded into an ns_cache called -secret_tokens. When a new signed cookie is requested, a random +secret_tokens. When a new signed cookie is requested, a random token_id is returned out of the entire set of cached token_ids. In addition, a thread-persistent cache called tcl_secret_tokens is maintained on a per-thread basis.
Thus, the L2 ns_cache functions as a server-wide LRU cache that has a @@ -215,31 +215,31 @@ all secret tokens. Note that this is not an LRU cache because there is no cache eviction policy per se -- the cache is cleared when the thread is destroyed by AOLserver. -
Storing information on a client always presents an additional security risk.
Since we are only validating the information and not trying to protect it as a secret, we don't use salt. Cryptographic salt is useful if you are -trying to protect information from being read (e.g., hashing passwords).
External SSL mechanisms (firewall, dedicated hardware, etc.) can be used by creating two pools of AOLservers. In one pool the servers should be configured with the location parameter of nssock module set to "https://yourservername". The servers in the other pool are configured as normal. The external SSL agent should direct SSL queries to the pool of secure servers, and it should direct non-SSL queries to the insecure servers. -
The pseudorandom number generator depends primarily on ns_rand, but is also seeded with ns_time and the number of page requests served since the server was started. The PRNG takes the SHA1(seed,ns_rand,ns_time,requests,clicks), and saves the first 40 bits as the seed for the next call to the PRNG in a thread-persistent global variable. The remaining 120 bits are rehashed to produce 160 bits of output. -
ad_user_login user_id Logs the user in as user user_id. Optional forever flag determines whether or not permanent cookies are issued.
ad_user_logout Logs the user out.
ad_check_password user_id password returns 0 or 1.
ad_change_password user_id new -password
ad_sign value Returns the digital signature of this value. Optional parameters allow for the specification of the secret used, the token_id used and the max_age for the signature. @@ -250,17 +250,17 @@ ad_set_signed_cookie name data Sets a signed cookie name with value data.
ad_get_signed_cookie name Gets the signed cookie name. It raises an error if the cookie has been tampered with, or if -its expiration time has passed.
ad_set_client_property module name data Sets a session property with name to value data for the module module. The optional secure flag specifies the property should only be set if the client is authorized for -secure access (ad_secure_conn_p is true). There is also an optional +secure access (ad_secure_conn_p is true). There is also an optional session_id flag to access data from sessions other than the current one.
ad_get_client_property module name data Gets a session property with name to for the module module. The optional secure flag specifies the property should only be retrieved if the client is authorized for secure access -(ad_secure_conn_p is true). There is also an optional -session_id flag to access data from sessions other than the current one.
+(ad_secure_conn_p is true). There is also an optional +session_id flag to access data from sessions other than the current one.
SessionTimeout the maximum time in seconds (default 1200) between requests that are part of the same session
SessionRenew the time in seconds (default 300) between reissue of the session cookie. The minimum time that can pass after a session @@ -269,30 +269,30 @@ set on a single page even if there are multiple images that are being downloaded.
SessionLifetime the maximum possible lifetime of a session in seconds (default 604800 = 7 days)
NumberOfCachedSecretTokens the number of secret tokens to -cache. (default 100)
The pseudorandom number generator used in the OpenACS is cryptographically weak, -and depends primarily on the randomness of the ns_rand function +and depends primarily on the randomness of the ns_rand function for its randomness. The implementation of the PRNG could be substantially improved. -
Add a password argument. It is non-optimal to make the default behavior to assume that the password was provided. -
The secret tokens pool is currently static. Ideally, this pool should be changed on a random but regular basis, and the number of secret_tokens increased as the number of users come to the web site.
Since the security of the entire system depends on the secret tokens pool, access to the secret tokens table should be restricted and accessible via a strict PL/SQL API. This can be done by revoking standard SQL permissions on the table for the AOLserver user and giving those permissions to a PL/SQL -package.
Deferring session to creation until the second hit from a browser seems to be a good way of preventing a lot of overhead processing for robots. If we do this, send cookie on first hit to test if cookies are accepted, then actually allocate on second hit. To preserve a record of the first hit of the session, just include any info about that first hit in the probe cookie sent. Look at how usca_p (user session cookie attempted) is used in OpenACS 3.x ecommerce. -
Currently there are only session properties. Because sessions have a maximum life, properties have a maximum life. It would be nice to expand the interface to allow for more persistent properties. In the past, there was a @@ -305,7 +305,7 @@ can be shared between concurrent sessions). The applications should have control over the deletion patterns, but should not be able to ignore the amount of data stored. -
It would be nice to keep some info about sessions: first hit, last hit, and URLs visited come to mind. Both logging and API for accessing this info would be nice. WimpyPoint is an application that already wants to use this @@ -314,7 +314,7 @@ analyzers (leaving it in server memory for applications to access). Putting it into the database at all is probably too big a hammer. Certainly putting it into the database on every hit is too big a hammer. -
Two trends drive the requirement for removing cookie dependence. WAP browsers that do not have cookies, and publc perceptions of cookies as an invasion of privacy. The rely on the cookies mechanism in HTTP to distinguish one request from the next, and we trust it to force requests from the same @@ -333,21 +333,21 @@ Both of these problems can be mitigated by doing detection of cookie support (see the section on robot detection). To help deal with the first problem, One could also make the restriction that secure sessions are only allowed over -cookied HTTP.
This section is not meant to be a comprehensive analysis of the vulnerabilities of the security system. Listed below are possible attack points for the system; these vulnerabilities are currently theoretical in nature. The major cryptographic vulnerability of the system stems from the pseudorandom nature of the random number generators used in the system.
Cryptographically weak PRNG see -above.
Dependence on sample +above.
Dependence on sample SQL command The list of random token that are placed in the secret tokens cache is randomly chosen by the Oracle -sample command. This command may not be +sample command. This command may not be entirely random, so predicting the contents of the secret tokens cache may not be as difficult as someone may anticipate.
Dependence on -ns_rand The actual token that is +ns_rand The actual token that is chosen from the cache to be used is chosen by a call to -ns_rand.
ad_secure_conn_p +ns_rand.
ad_secure_conn_p As discussed above, the security of the secure sessions authentication system is dependent upon this function.
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/security-notes.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/security-notes.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/security-notes.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/security-notes.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,13 +1,13 @@ -OpenACS 4 Security Notes +
OpenACS 4 Security Notes by Richard Li
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.The security system was designed for security. Thus, decisions requiring trade-offs between ease-of-use and security tend to result in a system that may not be as easy to use but is more secure. -
+
If a user switches to HTTPS after logging into the system via HTTP, the user must obtain a secure token. To insure security, the only way to @@ -22,8 +22,8 @@ issues a secure token, the method of authentication must be as strong as the method of transmission.
If a developer truly does not want such a level of protection, this system can be disabled via source code modification only. This can be accomplished -by commenting out the following lines in the sec_handler -procedure defined in security-procs.tcl:
+by commenting out the following lines in the sec_handler +procedure defined in security-procs.tcl:if { [ad_secure_conn_p] && ![ad_login_page] } { set s_token_cookie [ns_urldecode [ad_get_cookie "ad_secure_token"]] @@ -36,7 +36,7 @@The source code must also be edited if the user login pages have been moved out of an OpenACS system. This information is contained by the -ad_login_page procedure in security-procs.tcl:
+ad_login_page procedure in security-procs.tcl:ad_proc -private ad_login_page {} { @@ -55,5 +55,5 @@The set of string match expressions in the procedure above should be extended appropriately for other registration pages. This procedure does not use -ad_parameter or regular expressions for performance reasons, as +ad_parameter or regular expressions for performance reasons, as it is called by the request processor.
($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/security-requirements.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/security-requirements.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/security-requirements.html 29 Apr 2003 05:58:34 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/security-requirements.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,19 +1,19 @@ -OpenACS 4 Security Requirements +
OpenACS 4 Security Requirements by Richard Li
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Virtually all web sites support personalized content based on user identity. The level of personalization may be as simple as displaying the name of the user on certain pages or can be as sophisticated as dynamically recommending sections of site that the user may be interested in based on prior browsing history. In any case, the user's identity must be validated and made available to the rest of the system. In addition, sites such as ecommerce vendors require that the user identity be securely validated. -
The security system consists of a number of subsystems.
Signed Cookies
Cookies play a key role in storing user information. However, since they are Index: openacs-4/packages/acs-core-docs/www/software-versions.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/Attic/software-versions.html,v diff -u -r1.1.2.7 -r1.1.2.8 --- openacs-4/packages/acs-core-docs/www/software-versions.html 4 May 2003 06:30:03 -0000 1.1.2.7 +++ openacs-4/packages/acs-core-docs/www/software-versions.html 7 May 2003 17:40:59 -0000 1.1.2.8 @@ -1,5 +1,5 @@ -
Chapter�2.�Prerequisite Software Table of Contents
+
Chapter�2.�Prerequisite Software Table of Contents
by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. Index: openacs-4/packages/acs-core-docs/www/subsites-design.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/subsites-design.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/subsites-design.html 29 Apr 2003 05:58:34 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/subsites-design.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,11 +1,11 @@ -OpenACS 4 Subsites Design Document +
OpenACS 4 Subsites Design Document by Rafael H. Schloming
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.*Note* This document has not gone through the any of the required QA process yet. It is being tagged as stable due to high -demand.
An OpenACS 4 subsite is a managed suite of applications that work together for +demand.
An OpenACS 4 subsite is a managed suite of applications that work together for a particular user community. This definition covers a very broad range of requirements: from a Geocities style homepage where a user can install whatever available application he wants (e.g. a single user could have their @@ -18,7 +18,7 @@ the Request Processor. Since the design and implementation directly associated with subsites is actually minimal, a discussion of subsites design is, in fact, a discussion of how core OpenACS 4 components implicitly support -subsites as a whole.
The subsites problem actually has several quite diverse origins. It was +subsites as a whole.
The subsites problem actually has several quite diverse origins. It was originally recognized as a toolkit feature in the form of "scoping". The basic concept behind scoping was to allow one scoped OpenACS installation to behave as multiple unscoped OpenACS installations so that one @@ -33,20 +33,20 @@ consistent theme among all of them is the concept that various areas of the web site have their own private version of a module. Because this theme is so dominant, this is the primary problem that the OpenACS4 implementation of -subsites addresses.
The current implementation of package instances and subsites allows +subsites addresses.
The current implementation of package instances and subsites allows extremely flexible URL configurations. This has the benefit of allowing multiple instances of the same package to be installed in one subsite, but can potentially complicate the process of integrating packages with each other since it is likely people will want packages that live at non standard URLs to operate together. This requirement would cause some packages to have more configuration options than normal since hard-coding the URLs would not -be feasible anymore.
This section will cover all the APIs relevant to subsites, and so will consist of portions of the APIs of several systems.
Packages
The following package is provided for instantiation of packages. The apm_package.new function can be used to create a package of any type known to the system. The apm_package_types table can be queried for a list of installed packages. (See APM docs for more detail XXX: insert link here)
-create or replace package apm_package +create or replace package apm_package as function new ( @@ -111,7 +111,7 @@ node URL. The object_id column contains the object mounted on the URL represented by the node. In most cases this will be a package instance.-create table site_nodes ( +create table site_nodes ( node_id constraint site_nodes_node_id_fk references acs_objects (object_id) constraint site_nodes_node_id_pk @@ -139,7 +139,7 @@The following package is provided for creating nodes.
-create or replace package site_node +create or replace package site_node as -- Create a new site node. If you set directory_p to be 'f' then you @@ -186,20 +186,20 @@ specific site node, the following request processor APIs can be used to allow the package to serve content appropriate to the package instance.-[ad_conn node_id] +[ad_conn node_id] [ad_conn package_id] [ad_conn package_url] -The subsites implementation doesn't really have it's own data model, although it depends heavily on the site-nodes data model, and the APM -data model.
The primary elements of the subsite user interface consist of the subsite +data model.
The primary elements of the subsite user interface consist of the subsite admin pages. These pages are divided up into two areas: Group administration, and the site map. The group administration pages allow a subsite administrator to create and modify groups. The site map pages allow a subsite administrator to install, remove, configure, and control access to packages. The site map interface is the primary point of entry for most of the things a -subsite administrator would want to do.
The current subsites implementation addresses the most basic functionality +subsite administrator would want to do.
The current subsites implementation addresses the most basic functionality required for subsites. It is likely that as developers begin to use the subsites system for more sophisticated projects, it will become necessary to develop tools to help build tightly integrated packages. The general area @@ -210,4 +210,4 @@ a particular configuration of site nodes/packages. As we build more fundamental applications that can be applied in more general areas, this feature will become more and more in demand since more problems will be -solvable by configuration instead of coding.
Prev Home Next OpenACS 4 Subsites Requirements Up OpenACS 4.6.3 Package Manager Requirements
docs@openacs.orgView comments on this page at openacs.org +solvable by configuration instead of coding.
Prev Home Next OpenACS 4 Subsites Requirements Up OpenACS 4.6.3 Package Manager Requirements
docs@openacs.orgView comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/subsites-requirements.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/subsites-requirements.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/subsites-requirements.html 29 Apr 2003 05:58:34 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/subsites-requirements.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,29 +1,29 @@ -OpenACS 4 Subsites Requirements +
OpenACS 4 Subsites Requirements by Rafael H. Schloming and Dennis Gregorovic
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -The following is a requirements document for OpenACS 4 Subsites, part of the OpenACS 4 Kernel. The Subsites system allows one OpenACS server instance to serve multiple user communities, by enabling the suite of available OpenACS -applications to be customized for defined user communities.
Many online communities are also collections of discrete subcommunities, +applications to be customized for defined user communities.
Many online communities are also collections of discrete subcommunities, reflecting real-world relationships. For example, a corporate intranet/extranet website serves both units within the company (e.g., offices, departments, teams, projects) and external parties (e.g., customers, partners, vendors). Subsites enable a single OpenACS instance to provide each subcommunity with its own "virtual website," by assembling OpenACS packages that together deliver a feature set tailored to the needs of the -subcommunity.
The OpenACS subsite system allows a single OpenACS installation to serve multiple +subcommunity.
The OpenACS subsite system allows a single OpenACS installation to serve multiple communities. At an implementation level this is primarily accomplished by having an application "scope" its content to a particular package instance. The request processor then figures out which package_id a particular URL references -and then provides this information through the ad_conn api ([ad_conn -package_id], [ad_conn package_url]).
The other piece of the subsite system is a subsite package that provides +and then provides this information through the ad_conn api ([ad_conn +package_id], [ad_conn package_url]).
The other piece of the subsite system is a subsite package that provides subsite admins a "control panel" for administering their subsite. This is the same package used to provide all the community core functionality available at the "main" site which is in fact simply another -subsite.
The Subsites functionality is intended for use by two different classes of +subsite.
The Subsites functionality is intended for use by two different classes of users:
Package programmers (referred to as 'the programmer') must develop subcommunity-aware applications.
Site administrators (referred to as 'the administrator') use subsites to provide tailored "virtual websites" to different @@ -41,18 +41,18 @@ http://www.company.com/offices/boston/bboard, and similarly for the Austin office. At this point, the Boston and Austin office admins can customize the configurations for each of their bboards, or they can just use the -defaults.
Test plan (Not available yet)
A subsite API is required for programmers to ensure their packages are +defaults.
Test plan (Not available yet)
A subsite API is required for programmers to ensure their packages are subsite-aware. The following functions should be sufficient for this:
10.10.0 Package creation
The system must provide an API call to create a package, and it must be possible for the context (to which the package belongs) to be specified.
10.20.0 Package deletion
The system must provide an API call to delete a package and all related objects in the subsite's context.
10.30.0 Object's package information
Given an object ID, the system must provide an API call to determine the package (ID) to which the object belongs.
10.40.0 URL from package
Given a package (ID), the system must provide an API call to return the canonical URL for that package.
10.50.0 Main subsite's package_id
The system must provide an API call to return a package ID corresponding -to the main subsite's package ID (the degenerate subsite).
The Programmer's User Interface
There is no programmer's UI, other than the API described above.
The Administrator's User Interface
The UI for administrators is a set of HTML pages that are used to drive +to the main subsite's package ID (the degenerate subsite).
The Programmer's User Interface
There is no programmer's UI, other than the API described above.
The Administrator's User Interface
The UI for administrators is a set of HTML pages that are used to drive the underlying API for package instance management (i.e. adding, removing, or altering packages). It is restricted to administrators of the current subsite such that administrators can only manage their own subsites. Of course, Site-Wide Administrators can manage all subsites.
20.10.0 Package creation
20.10.1 The administrator should be able to create a package and make it available at a URL underneath the subsite.
20.20.0 Package deactivation
20.20.1 The administrator should be able to deactivate any package, causing it to be inaccessible to users.
20.20.5 Deactivating a package makes the package no longer accessible, but it does not remove data created within the context of -that package.
View comments on this page at openacs.org +that package.View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/subsites.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/subsites.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/subsites.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/subsites.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,11 +1,11 @@ -Writing OpenACS 4.6.3 Application Pages +
Writing OpenACS 4.6.3 Application Pages By Rafael H. Schloming and Pete Su
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -In this document, we'll examine the user interface pages of the Notes application in more detail, covering two separate aspects of page development in OpenACS 4.6.3. First, we'll talk about the code needed to make @@ -14,7 +14,7 @@ form-based user interfaces in OpenACS 4.6.3. While these seem like unrelated topics, they both come up in the example page that we are going to look at, so it makes sense to address them at the same time. -
As you will recall from the packages tutorial, the Request Processor (RP) and Package Manager (APM) in OpenACS 4.6.3 allow site administrators to define an arbitrary mapping from URLs in the site to @@ -25,63 +25,63 @@ particular URL. The tutorial also showed how a given URL is translated into a physical file to serve using the site map. We'll repeat this description here, assuming that you have mounted an -instance of Notes at the URL /notes as we did in the packages-example: +instance of Notes at the URL /notes as we did in the packages-example:
-AOLserver receives your request for the URL /notes/somepage. +AOLserver receives your request for the URL /notes/somepage.
This URL is passed to the request processor.
The RP looks up the URL in the site map, and sees that the object -mounted at that location is an instance of the notes +mounted at that location is an instance of the notes application.
The RP asks the package manager where in the file system the Notes package lives. In the standard case, this would be -ROOT/packages/notes. +ROOT/packages/notes.
The RP translates the URL to serve a page relative to the page root of the application, which is -ROOT/packages/notes/www/. Therefore, the page that is -finally served is ROOT/packages/notes/www/hello.html, +ROOT/packages/notes/www/. Therefore, the page that is +finally served is ROOT/packages/notes/www/hello.html, which is what we wanted.
What is missing from this description is a critical fact for application developers: In addition to working out what file to serve, the RP also stores information about which package instance the file belongs to into the AOLserver connection environment. The following -ad_conn interfaces can be used to extract this +ad_conn interfaces can be used to extract this information: -
- [ad_conn package_url]
+
- [ad_conn package_url]
If the URL refers to a package instance, this is the URL to the root of the tree where the package is mounted. -
- [ad_conn package_id]
+
- [ad_conn package_id]
If the URL refers to a package instance, this is the ID of that package instance. -
- [ad_conn package_key] +
- [ad_conn package_key]
If the URL refers to a package instance, this is the unique key name of the package. -
- [ad_conn extra_url] +
- [ad_conn extra_url]
If we found the URL in the site map, this is the tail of the URL following the part that matched a site map entry.
In the Notes example, we are particularly interested in the -package_id field. If you study the data model and code, +package_id field. If you study the data model and code, you'll see why. As we said before in the data modeling tutorial, the Notes application points the -context_id of each Note object that it creates to the -package instance that created it. That is, the context_id -corresponds exactly to the package_id that comes in from +context_id of each Note object that it creates to the +package instance that created it. That is, the context_id +corresponds exactly to the package_id that comes in from the RP. This is convenient because it allows the administrator and the owner of the package to easily define access control policies for all the notes in a particular instance just my setting permissions on the package instance itself.
The code for adding and editing notes, in -notes/www/add-edit.tcl, shows how this works. At the top -of the page, we extract the package_id and use it to do +notes/www/add-edit.tcl, shows how this works. At the top +of the page, we extract the package_id and use it to do permission checks:
@@ -103,7 +103,7 @@ for each action.Later, when we actually create a note, the SQL that we run ensures -that the context_id is set the right way: +that the context_id is set the right way:
db_dml new_note { @@ -127,25 +127,25 @@ without generating a lot of duplicated HTML in your pages. It also encapsulates most of the common logic that we use in dealing with forms, which we'll discuss next. -The forms API is pretty simple: You use calls in the -template::form namespace in your Tcl script to create +template::form namespace in your Tcl script to create form elements. The final template page then picks this stuff up and lays the form out for the user. The form is set up to route submit buttons and whatnot back to the same Tcl script that set up the form, so your Tcl script will also contain the logic needed to process these requests.
So, given this outline, here is a breakdown of how the forms code -works in the add-edit.tcl page. First, we create a form object -called new_note: +works in the add-edit.tcl page. First, we create a form object +called new_note:
template::form create new_noteAll the forms related code in this page will refer back to this -object. In addition, the adp part of this page does +object. In addition, the adp part of this page does nothing but display the form object:
@@ -179,9 +179,9 @@ }-The if_request call returns true if we are asking the +The if_request call returns true if we are asking the page to render the form for the first time. That is, we are rendering -the form to ask the user for input. The tcl part of a +the form to ask the user for input. The tcl part of a form page can be called in 3 different states: the initial request, the initial submission, and the validated submission. These states reflect the typical logic of a forms based page in OpenACS: @@ -194,16 +194,16 @@ Finally, control passes to the page that performs the update in the database.
-The rest of the if condition figures out if we are +The rest of the if condition figures out if we are creating a new note or editing an existing note. If -note_id is passed to us from the calling page, we assume +note_id is passed to us from the calling page, we assume that we are editing an existing note. In this case, we do a database query to grab the data for the note so we can populate the form with it.
The next two calls create form elements where the user can insert or edit the title and body of the Note. The interface to -template::element is pretty straightforward. +template::element is pretty straightforward.
Finally, the code at the bottom of the page performs the actual database updates when the form is submitted and validated: @@ -246,7 +246,7 @@ the HTML rendering, input validation and database transaction logic on your behalf. This means that you can write pages without duplicating all of that code in every set of pages that uses forms. -
To watch all of this work, use the installer to update the Notes package with the new code that you grabbed out of CVS or the package repository, mount an instance of Notes somewhere in your server and @@ -264,7 +264,7 @@ simple, and special purpose application to something that has the potential to be a very useful, general-purpose tool, complete with multi-user features, access control, and centralized administration. -
In OpenACS 4.6.3, application pages and scripts can be aware of the package instance, or subsite in which they are executing. This is a powerful general purpose mechanism that can be used to structure web services Index: openacs-4/packages/acs-core-docs/www/tcl-doc.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/tcl-doc.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/tcl-doc.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/tcl-doc.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,36 +1,36 @@ -
Documenting Tcl Files: Page Contracts and Libraries +
Documenting Tcl Files: Page Contracts and Libraries by Jon Salz on 3 July 2000
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -
Tcl procedures: /packages/acs-kernel/tcl-documentation-procs.tcl
We use functions to document Tcl files and a web-based user -interface for browsing the documentation:
ad_page_contract: Every Tcl page +
Tcl procedures: /packages/acs-kernel/tcl-documentation-procs.tcl
We use functions to document Tcl files and a web-based user +interface for browsing the documentation:
ad_page_contract: Every Tcl page has a contract that explicitly defines what inputs the page -expects (with more precision than ad_page_variables) and +expects (with more precision than ad_page_variables) and incorporates metadata about the page (what used to live in the top-of-page -comment). Like ad_page_variables, ad_page_contract -also sets the specified variables in the context of the Tcl page.
ad_library: To be +comment). Like ad_page_variables, ad_page_contract +also sets the specified variables in the context of the Tcl page.
ad_library: To be called at the top of every library file (i.e., all files in the -/tcl/ directory under the server root and -*-procs.tcl files under /packages/).
+/tcl/ directory under the server root and +*-procs.tcl files under /packages/).
This has the following benefits:
Facilitates automatic generation of human-readable documentation.
Promotes security, by introducing a standard and automated way to check inputs to scripts for correctness.
Allows graphical designers to determine easily how to customize sites' UIs, e.g., what properties are available in templates.
Allows the request processor to be intelligent: a script can specify in its contract which type of abstract document it returns, and the request processor can transform it automatically into something useful to a particular user agent. (Don't worry about this for -now - it's not complete for ACS 3.4.)
+Currently ad_page_contract serves mostly as a replacement for +ad_page_variables. Eventually, it will be integrated closely with the documents API so that each script's contract will document precisely the set of properties available to graphical designers in templates. (Document API integration is subject to change, so we don't desrribe it here yet; for now, you can just consider -ad_page_contract a newer, better, documented -ad_page_variables.) -
Let's look at an example usage of ad_page_contract:
+ad_page_contract a newer, better, documented +ad_page_variables.) +Let's look at an example usage of ad_page_contract:
# /packages/acs-kernel/api-doc/www/package-view.tcl ad_page_contract { @@ -55,83 +55,83 @@Note that: -
By convention, ad_page_contract should be preceded +
By convention, ad_page_contract should be preceded by a comment line containing the file's path. The comment is on line 1, and the contract starts on line 2. -
ad_page_contract's first argument is -the list of expected arguments from the HTTP query (version_id, -public_p, kind, and format). Like -ad_page_variables, ad_page_contract sets the +
ad_page_contract's first argument is +the list of expected arguments from the HTTP query (version_id, +public_p, kind, and format). Like +ad_page_variables, ad_page_contract sets the corresponding Tcl variables when the page is executed.
Arguments can have defaults, specified using the same -syntax as in the Tcl proc (a two-element list where the first +syntax as in the Tcl proc (a two-element list where the first element is the parameter name and the second argument is the default value).
Arguments can have flags, specified by following the name of the query argument with a colon and one or more of the following -strings (separated by commas):
optional: the query argument doesn't +strings (separated by commas):
optional: the query argument doesn't need to be provided; if it's not, the variable for that argument simply won't be set. For instance, if I call the script above without a -public_p in the query, then in the page body [info exists +public_p in the query, then in the page body [info exists public_p] will return 0. -
integer: the argument must be an integer -(ad_page_contract will fail and display and error if not). This +
integer: the argument must be an integer +(ad_page_contract will fail and display and error if not). This flag, like the next, is intended to prevent clients from fudging query arguments to trick scripts into executing arbitrary SQL. -
sql_identifier: the argument must be a SQL -identifier (i.e., [string is wordchar $the_query_var] must +
sql_identifier: the argument must be a SQL +identifier (i.e., [string is wordchar $the_query_var] must return true). -
trim: the argument will be [string +
trim: the argument will be [string trim]'ed. -
multiple: the argument may be specified +
multiple: the argument may be specified arbitrarily many times in the query string, and the variable will be set to a list of all those values (or an empty list if it's unspecified). This is -analogous to the -multiple-list flag to -ad_page_variables, and is useful for handling form input -generated by <SELECT MULTIPLE> tags and checkboxes.
For instance, if dest_user_id:multiple is specified in the +analogous to the -multiple-list flag to +ad_page_variables, and is useful for handling form input +generated by <SELECT MULTIPLE> tags and checkboxes.
For instance, if dest_user_id:multiple is specified in the contract, and the query string is
?dest_user_id=913&dest_user_id=891&dest_user_id=9-then $dest_user_id is set to [list 913 891 9]. +then $dest_user_id is set to [list 913 891 9]. -
array: the argument may be specified +
array: the argument may be specified arbitrarily many times in the query string, with parameter names with -suffixes like _1, _2, _3, etc. The +suffixes like _1, _2, _3, etc. The variable is set to a list of all those values (or an empty list if none are -specified).
For instance, if dest_user_id:array is specified in the +specified).
For instance, if dest_user_id:array is specified in the contract, and the query string is
?dest_user_id_0=913&dest_user_id_1=891&dest_user_id_2=9-then $dest_user_id is set to [list 913 891 9].
You can provide structured, HTML-formatted documentation for your +then $dest_user_id is set to [list 913 891 9].
You can provide structured, HTML-formatted documentation for your contract. Note that format is derived heavily from Javadoc: a general description of the script's functionality, followed optionally by -a series of named attributes tagged by at symbols (@). You are +a series of named attributes tagged by at symbols (@). You are encouraged to provide:
A description of the functionality of the page. If the description contains more than one sentence, the first sentence should be a brief summary. -
A @param tag for each allowable query +
A @param tag for each allowable query argument. The format is
@param parameter-name description... -An @author tag for each author. Specify the -author's name, followed his or her email address in parentheses.
A @creation-date tag indicating when the -script was first created.
A @cvs-id tag containing the page's CVS -identification string. Just use $Id: tcl-documentation.html,v 1.2 +
An @author tag for each author. Specify the +author's name, followed his or her email address in parentheses.
A @creation-date tag indicating when the +script was first created.
A @cvs-id tag containing the page's CVS +identification string. Just use $Id: tcl-documentation.html,v 1.2 2000/09/19 07:22:35 ron Exp $ when creating the file, and CVS will substitute an appropriate string when you check the file in.
- These @ tags are optional, but highly recommended!
+ad_library provides a replacement for the informal documentation (described above) found at the beginning of every Tcl page. Instead of:
@@ -162,11 +162,11 @@Note that format is derived heavily from Javadoc: a general description of the script's functionality, followed optionally by a series of named -attributes tagged by at symbols (@). HTML formatting is allowed. +attributes tagged by at symbols (@). HTML formatting is allowed. You are encouraged to provide: -
An @author tag for each author. Specify the -author's name, followed his or her email address in parentheses.
A @creation-date tag indicating when the -script was first created.
A @cvs-id tag containing the page's CVS -identification string. Just use $Id: tcl-documentation.html,v 1.2 +
An @author tag for each author. Specify the +author's name, followed his or her email address in parentheses.
A @creation-date tag indicating when the +script was first created.
A @cvs-id tag containing the page's CVS +identification string. Just use $Id: tcl-documentation.html,v 1.2 2000/09/19 07:22:35 ron Exp $ when creating the file, and CVS will substitute an appropriate string when you check the file in.
($Id$)View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/templates.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/templates.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/templates.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/templates.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,8 +1,8 @@ -Using Templates in OpenACS 4.6.3 By Pete Su
+Using Templates in OpenACS 4.6.3 By Pete Su
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -The OpenACS 4.6.3 Template System (ATS) is designed to allow developers to cleanly separate application logic from display logic. The intent is to have all of the logic related to @@ -13,12 +13,12 @@ graphic designers to work more independently.
In ATS, you write two files for every user-visible page in the -system. One is a plain .tcl file and the other is a -special .adp file. The .tcl file runs a +system. One is a plain .tcl file and the other is a +special .adp file. The .tcl file runs a script that sets up a set of name/value bindings that we call data sources. These data sources are generally the results of Tcl and/or database queries or some combination thereof. The template system automatically makes -them available to the .adp file, or the display part of +them available to the .adp file, or the display part of the template, which is written in a combination of HTML, special template related tags, and data source substitutions.
@@ -29,7 +29,7 @@ actually add notes to the database, how to provide a separate instance of the Notes application to every user and how to design appropriate access control policies for the system. -
In order for the Notes application to be useful, we have to allow users to enter data into the database. Typically, this takes two pages: one that displays a form for data entry, and another page that @@ -39,10 +39,10 @@ the system since we won't be displaying much data, but we'll cover more on that end later.
-The .tcl file for the form entry template is pretty +The .tcl file for the form entry template is pretty simple. Here, the only thing we need from the database is a new ID for the note object to be inserted. Open up a file called -note-add.tcl in the ROOT/packages/notes/www +note-add.tcl in the ROOT/packages/notes/www directory, and put the following code in it:
@@ -80,34 +80,34 @@ Some things to note about this code:
The procedure ad_page_contract is -always the first thing a .tcl file calls, if it's under +always the first thing a .tcl file calls, if it's under the www/ directory (i.e. not a Tcl library file). It does validation of input values from the HTTP request (i.e. form variables) and in -this case, the -properties clause is used to set up the -data sources that we will ship over to the .adp part of +this case, the -properties clause is used to set up the +data sources that we will ship over to the .adp part of the page. In this case, we only use the simplest possible kind of data -source, called a onevalue, which hold just a single +source, called a onevalue, which hold just a single string value. Later on, we'll see how to use more powerful kinds of data sources for representing multiple rows from an SQL query. You also include overall documentation for the page in the contract, and OpenACS has automatic tools that extract this documentation and make it browsable.
-After being declared in the ad_page_contract, each +After being declared in the ad_page_contract, each property is just a simple Tcl variable. The template system passes the -final value of the variable to the .adp template when the -.tcl file is processed. +final value of the variable to the .adp template when the +.tcl file is processed.
-The call ad_return_template tells the template system -what .adp template page to fetch to display the +The call ad_return_template tells the template system +what .adp template page to fetch to display the properties that have been processed. By default, the template system -will look for a file by the same name as the .tcl file -that just ran, but with an .adp extension. +will look for a file by the same name as the .tcl file +that just ran, but with an .adp extension.
-Next we write the corresponding .adp page. This page +Next we write the corresponding .adp page. This page outputs HTML for the form, and also contains placeholders whose values -are substituted in from the properties set up by the .tcl -file. Create a file called note-add.adp in your editor, +are substituted in from the properties set up by the .tcl +file. Create a file called note-add.adp in your editor, and insert this text:
@@ -136,7 +136,7 @@ Master templates allow you do centralize display code that is used throughout an application in a single file. In this case, we intend to have a master template that does the standard page headers and footers -for us - create the master.adp file, which looks like +for us - create the master.adp file, which looks like this:@@ -152,18 +152,18 @@ The main subtlety in this code is the inline Tcl code for running procs to build the header, footer, context bar, etc. Also, note the property substitutions that happen here, the values of which are set -up in the <property> tags in the slave page. +up in the <property> tags in the slave page.After putting all these files into -ROOT/packages/notes/www, you should be able to go to -/notes/ URL for your server and see the input form. -
+ROOT/packages/notes/www, you should be able to go to +/notes/ URL for your server and see the input form. +
Templates separate application logic from display logic by requiring the developer to write pages in two stages, one file for database queries and application logic, and another for display. In OpenACS 4.6.3, the -logic part of the page is just a .tcl that sets up +logic part of the page is just a .tcl that sets up data sources that are used by the display part of the page. The -display part of the page is an .adp file with some +display part of the page is an .adp file with some special tags and notations for dealing with display logic and inserting properties into the text of the page. Later on we'll get into templates more deeply, and show how to use database queries as Index: openacs-4/packages/acs-core-docs/www/tutorial-advanced.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/tutorial-advanced.html,v diff -u -r1.1.2.6 -r1.1.2.7 --- openacs-4/packages/acs-core-docs/www/tutorial-advanced.html 4 May 2003 06:30:03 -0000 1.1.2.6 +++ openacs-4/packages/acs-core-docs/www/tutorial-advanced.html 7 May 2003 17:40:59 -0000 1.1.2.7 @@ -1,18 +1,18 @@ -
Advanced Topics Important
This section is a work in progress.
+
Advanced Topics Important
This section is a work in progress.
by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -This tutorial covers topics which are not essential to creating a minimal working package. Each section can be used independently of all of the others; all sections assume that you've completed the basic tutorial.
How to enforce security so that users can't change other users records
How to use the content management tables so that ... what?
How to change the default stylesheets for Form Builder HTML forms.
How to make your package searchable with OpenFTS/Oracle
How to make your package send email notifications
How to prepare pagelets for inclusion in other pages
How and when to put procedures in a tcl procedure library
How to add general_comments to your pages
More on ad_form - data validation, other stuff. (plan to draw from Jon Griffin's doc)
How and when to implement caching
partialquery in xql
How to use the html/text entry widget to get the - "does this look right" confirm page
APM package dependencies
We need a way to delete records. We'll create a - recursive confirmation page.
Add this column to the table_def in index.tcl
{delete "" {} {<td><a href="note-delete?note_id=$note_id">Delete</a></td>}}Create the delete confirmation/execution page.
[service0@yourserver www]$ emacs note-delete.tclad_page_contract { + "does this look right" confirm pageAPM package dependencies
We need a way to delete records. We'll create a + recursive confirmation page.
Add this column to the table_def in index.tcl
{delete "" {} {<td><a href="note-delete?note_id=$note_id">Delete</a></td>}}Create the delete confirmation/execution page.
[service0@yourserver www]$ emacs note-delete.tclad_page_contract { A page that gets confirmation and then delete notes. @author joel@aufrecht.org @@ -41,18 +41,18 @@ ad_returnredirect "index" ad_script_abort }This page requires a -note_id to determine which record +note_id to determine which record should be deleted. It also looks for a confirmation variable, which should initially be absert. If it is absent, we create a form to allow the user to confirm the deletion. Note that in -entry-edit.tcl we used ad_form to access the Form Template +entry-edit.tcl we used ad_form to access the Form Template commands; here, we call them directly because we don't need the extra features of ad_form. The form calls itself, but with hidden variables carrying both -note_id and -confirm_p. If confirm_p is present, +note_id and +confirm_p. If confirm_p is present, we delete the record, set redirection back to the index, and abort -script execution.
The database commands:
[service0@yourserver www]$ emacs note-delete.xql<?xml version="1.0"?> +script execution.The database commands:
[service0@yourserver www]$ emacs note-delete.xql<?xml version="1.0"?> <queryset> <fullquery name="do_delete"> <querytext> @@ -64,14 +64,14 @@ select samplenote__name(:note_id) </querytext> </fullquery> -</queryset>And the adp page:
[service0@yourserver www]$ emacs note-delete.adp<master> +</queryset>And the adp page:
[service0@yourserver www]$ emacs note-delete.adp<master> <property name="title">@title@</property> <property name="context">{@title@}</property> <h2>@title@</h2> <formtemplate id="note-del-confirm"></formtemplate> </form>The ADP is very simple. The -formtemplate tag outputs the HTML -form generated by the ad_form command with the matching name. Test it by adding the new files in the APM and then deleting a few samplenotes.
You can track comments for any ACS Object. Here we'll track +formtemplate tag outputs the HTML +form generated by the ad_form command with the matching name. Test it by adding the new files in the APM and then deleting a few samplenotes.
You can track comments for any ACS Object. Here we'll track comments for notes. On the notes.tcl/adp pair, which is used to display individual notes, we want to put a link to add comments at the bottom of the screen. If there are any comments, we want to @@ -92,13 +92,13 @@ there are comments. Then you pass the note id, which is also the acs_object id.
We put our two new variables in the notes.adp page.
<a href="@comment_add_url@">Add a comment</a> -@comments_html@Browse to the package manager. Click on - tutorialapp.
Click on Generate a distribution file +@comments_html@
Browse to the package manager. Click on + tutorialapp.
Click on Generate a distribution file for this package from the - filesystem. + filesystem.
Click on the file size - (37.1KB) - after the label Distribution - File: and save the file to - /tmp.
+ (37.1KB) + after the label Distribution + File: and save the file to + /tmp.
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/tutorial-database.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/tutorial-database.html,v diff -u -r1.1.2.6 -r1.1.2.7 --- openacs-4/packages/acs-core-docs/www/tutorial-database.html 4 May 2003 06:30:03 -0000 1.1.2.6 +++ openacs-4/packages/acs-core-docs/www/tutorial-database.html 7 May 2003 17:40:59 -0000 1.1.2.7 @@ -1,20 +1,20 @@ -Setting Up Database Objects +
Setting Up Database Objects by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -We create all database objects with scripts in the - samplenote/sql/ directory. All +
We create all database objects with scripts in the + samplenote/sql/ directory. All database scripts are database-specific and are thus in either - the samplenote/sql/oracle or - samplenote/sql/postgresql. + the samplenote/sql/oracle or + samplenote/sql/postgresql. Packages can support Oracle, PostgreSQL, or both.
The first file will be - samplenote-create.sql. The + samplenote-create.sql. The package manager requires a file with the name - packagekey-create.sql, + packagekey-create.sql, which it will run automatically when the package in installed. This file should create all tables and views.
Our package is going to store all of its information in - one table. It takes more than just a CREATE + one table. It takes more than just a CREATE TABLE command, however, because we want to integrate our table with the OpenACS system. By making each record in our table an OpenACS object, we gain access to the @@ -25,22 +25,22 @@ Comments are located within the source code, with each comment preceeding the relevant code. (More info about ACS Objects)
First, create the necessary subdirectories and add them - cvs as you go.
[service0@yourserver samplenote]$ cd /web/service0/packages/samplenote -[service0@yourserver samplenote]$ mkdir sql -[service0@yourserver samplenote]$ cvs add sql + cvs as you go.[service0@yourserver samplenote]$ cd /web/service0/packages/samplenote +[service0@yourserver samplenote]$ mkdir sql +[service0@yourserver samplenote]$ cvs add sql Directory /cvsroot/service0/packages/samplenote/sql added to the repository -[service0@yourserver samplenote]$ cd sql/ -[service0@yourserver sql]$ mkdir postgresql -[service0@yourserver sql]$ cvs add postgresql +[service0@yourserver samplenote]$ cd sql/ +[service0@yourserver sql]$ mkdir postgresql +[service0@yourserver sql]$ cvs add postgresql Directory /cvsroot/service0/packages/samplenote/sql/postgresql added to the repository -[service0@yourserver sql]$ cd postgresql/We break out the sql commands into several files that can +[service0@yourserver sql]$ cd postgresql/
We break out the sql commands into several files that can be called independently, and then call all of the create files from the master create file. The top of each sql file has some standard comments, including doc tags such as - @author which will be picked up + @author which will be picked up by the API browser. The string - $Id$ will automatically be - expanded when the file is checked in to cvs.
[service0@yourserver postgresql]$ emacs samplenote-create.sqlPaste this into the file and save and close.
Figure�8.2.�Database Creation Script - master create file
-- + $Id$ will automatically be + expanded when the file is checked in to cvs.[service0@yourserver postgresql]$ emacs samplenote-create.sqlPaste this into the file and save and close.
Figure�8.2.�Database Creation Script - master create file
-- -- packages/samplenote/sql/postgresql/samplenote-create.sql -- -- @author rhs@mit.edu @@ -50,7 +50,7 @@ -- \i samplenote-table-create.sql -\i samplenote-functions-create.sqlCreate the file to create the database table.
[service0@yourserver postgresql]$ emacs samplenote-table-create.sqlPaste this into the file and save and close.
Create the file to create the database table.
[service0@yourserver postgresql]$ emacs samplenote-table-create.sqlPaste this into the file and save and close.
Figure�8.3.�Database Creation Script - table
-- -- packages/samplenote/sql/postgresql/samplenote-table-create.sql -- -- @author rhs@mit.edu @@ -101,7 +101,7 @@ end;' language 'plpgsql'; select inline_0 (); drop function inline_0 (); -Create the file to create the functions used to manipulate records.
[service0@yourserver postgresql]$ emacs samplenote-functions-create.sqlPaste this into the file and save and close.
Create the file to create the functions used to manipulate records.
[service0@yourserver postgresql]$ emacs samplenote-functions-create.sqlPaste this into the file and save and close.
Figure�8.4.�Database Creation Script - functions
-- -- packages/samplenote/sql/postgresql/samplenote-functions-create.sql -- -- @author rhs@mit.edu @@ -196,7 +196,7 @@ end; ' language 'plpgsql';Create a database file to drop everything if the package - is uninstalled.
[service0@yourserver postgresql]$ emacs samplenote-drop.sqlFigure�8.5.�Database deletion script
-- packages/samplenote/sql/samplenote-drop.sql + is uninstalled.[service0@yourserver postgresql]$ emacs samplenote-drop.sqlFigure�8.5.�Database deletion script
-- packages/samplenote/sql/samplenote-drop.sql -- drop script -- -- @author rhs@mit.edu @@ -237,11 +237,11 @@ select acs_object_type__drop_type( 'samplenote', 't' - );Add the database files to cvs.
[service0@yourserver postgresql]$ cvs add *.sql + );Add the database files to cvs.
[service0@yourserver postgresql]$ cvs add *.sql cvs add: scheduling file `samplenote-create.sql' for addition cvs add: scheduling file `samplenote-drop.sql' for addition cvs add: use 'cvs commit' to add these files permanently -[service0@yourserver samplenote]$ cvs commit -m "new database files" +[service0@yourserver samplenote]$ cvs commit -m "new database files" cvs commit: Examining . cvs commit: Examining sql cvs commit: Examining sql/postgresql @@ -252,8 +252,8 @@ done (many lines omitted) done -[service0@yourserver samplenote]$
Run the create script manually to add your tables and functions.
[service0@yourserver samplenote]$ cd sql/postgresql/ -[service0@yourserver postgresql]$ psql -f samplenote-create.sql +[service0@yourserver samplenote]$Run the create script manually to add your tables and functions.
[service0@yourserver samplenote]$ cd sql/postgresql/ +[service0@yourserver postgresql]$ psql -f samplenote-create.sql psql:samplenote-table-create.sql:22: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'samplenote_pk' for table 'samplenote' psql:samplenote-table-create.sql:22: NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) @@ -283,7 +283,7 @@ (1 row) CREATE -[service0@yourserver postgresql]$If there are errors, use them to debug the sql file and try again. If there are errors in the database table creation, you may need to run the drop script to drop the table so that you can recreate it. The drop script will probably have errors since some of the things it's trying to drop may be missing. They can be ignored.
If there are errors creating the functions, you can re-run the function creation file directly after fixing it, because all of the functions are created with create or replace commands. This will also make it easier to fix mistakes within the functions that aren't apparent until the functions are used. And it will make upgrades easier.
Once you get the same output as shown above, test the drop script:
[service0@yourserver postgresql]$ psql -f samplenote-drop.sql +[service0@yourserver postgresql]$If there are errors, use them to debug the sql file and try again. If there are errors in the database table creation, you may need to run the drop script to drop the table so that you can recreate it. The drop script will probably have errors since some of the things it's trying to drop may be missing. They can be ignored.
If there are errors creating the functions, you can re-run the function creation file directly after fixing it, because all of the functions are created with create or replace commands. This will also make it easier to fix mistakes within the functions that aren't apparent until the functions are used. And it will make upgrades easier.
Once you get the same output as shown above, test the drop script:
[service0@yourserver postgresql]$ psql -f samplenote-drop.sql psql:samplenote-drop.sql:13: NOTICE: DROP PACKAGE: samplenote psql:samplenote-drop.sql:13: NOTICE: DROPPING FUNCTION: samplenote__delete psql:samplenote-drop.sql:13: NOTICE: DROPPING FUNCTION: samplenote__name Index: openacs-4/packages/acs-core-docs/www/tutorial-debug.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/tutorial-debug.html,v diff -u -r1.1.2.6 -r1.1.2.7 --- openacs-4/packages/acs-core-docs/www/tutorial-debug.html 4 May 2003 06:30:03 -0000 1.1.2.6 +++ openacs-4/packages/acs-core-docs/www/tutorial-debug.html 7 May 2003 17:40:59 -0000 1.1.2.7 @@ -1,13 +1,13 @@ -Debugging and Automated Testing Important
This section is a work in progress.
+
Debugging and Automated Testing Important
This section is a work in progress.
by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -PostgreSQL.�You can work directly with the database to do debugging steps like looking directly at tables and testing stored procedures. Start emacs. Type - M-x sql-postgres. Press enter for - server name and use openacs-dev for + M-x sql-postgres. Press enter for + server name and use openacs-dev for database name. You can use C-(up arrow) and C-(down arrow) for command history.
Hint: "Parse error near *" usually means that an xql file wasn't recognized, because the tcl file is choking on the *SQL* @@ -19,10 +19,10 @@ ?�searches�backward�
/�searches�forward.�
����������-
Make a list of basic tests to make sure it works
Test Num Action Expected Result 001 Browse to the index page while not logged in and + Make a list of basic tests to make sure it works
Test Num Action Expected Result 001 Browse to the index page while not logged in and while one or more notes exist. No edit or delete or add links should appear. 002 Browse to the index page while logged in. An Edit link should appear. Click on it. Fill out the form and click Submit. The text added in the form should be visible on the index page. Other things to test: try to delete someone else's note. Try to delete your own note. Edit your own note. - Search for a note.
View comments on this page at openacs.org + Search for a note.View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/tutorial-newpackage.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/tutorial-newpackage.html,v diff -u -r1.1.2.5 -r1.1.2.6 --- openacs-4/packages/acs-core-docs/www/tutorial-newpackage.html 4 May 2003 06:30:03 -0000 1.1.2.5 +++ openacs-4/packages/acs-core-docs/www/tutorial-newpackage.html 7 May 2003 17:40:59 -0000 1.1.2.6 @@ -1,49 +1,49 @@ -Creating a Package +
Creating a Package by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -To start developing new code in OpenACS, we build a new package. A package is a a discrete collection of web pages, tcl code, and database tables and procedures. A package can be installed, upgraded, and removed. It communicates with other packages through an API. This chapter walks you through the minimum steps to create a useful package, including writing documentation, setting up database tables and procedures, writing web pages, debugging, and automatic regression testing. -
You will need:
A computer with a working installation of OpenACS +
You will need:
A computer with a working installation of OpenACS 4.6. If you don't have this, see Installation Overview.
Example files, which are included in the standard OpenACS 4.6.3 distribution. -
We use the ACS Package Manager (APM) to add, remove, and +
We use the ACS Package Manager (APM) to add, remove, and upgrade packages. It handles package meta-data, such as lists of files that belong in the package. Each package is uniquely identified by a package key. To start developing a new package, use the APM to create an empty package with our new - package key, samplenote. This will create + package key, samplenote. This will create the initial directories, meta-information files, and database entries for a new package. (More info on APM) -
Browse to http://yourserver:8000/acs-admin/apm. -
Click Create a New Package.
Fill in the fields listed below. Tab through the rest. +
Browse to http://yourserver:8000/acs-admin/apm. +
Click Create a New Package.
Fill in the fields listed below. Tab through the rest. (Some will change automatically. Don't mess with those.)
- Package Key: - samplenote
- Package Name: - Notes + Package Key: + samplenote
+ Package Name: + Notes
- Package Plural: - Notes
- Initial Version: - 0.1d -
Summary: - This is my first package. + Package Plural: + Notes
+ Initial Version: + 0.1d +
Summary: + This is my first package.
At the bottom, click - Create Package. + Create Package.
This creates a package rooted at - /web/service0/packages/samplenote. + /web/service0/packages/samplenote. This is the "home directory" of our new package, and all - files in the package will be within this directory.
In order to see your work in progress, you must create a + files in the package will be within this directory.
In order to see your work in progress, you must create a map between the URL space of incoming requests and the package. You do this by mounting the package in the Site Map. This creates a link between the incoming URL and an @@ -53,52 +53,52 @@ code and tables. This requires that a package be developed package-aware. You'll see how to do that in this tutorial.
Browse to -http://yourserver.test:8000/admin/site-map/.
Click the new sub - folder link on the top row in the - Site Map table.
Type note -and click New.
This creates a new row called -note. In the new row, click the new -application link
Type Sample Note where +http://yourserver.test:8000/admin/site-map/.
Click the new sub + folder link on the top row in the + Site Map table.
Type note +and click New.
This creates a new row called +note. In the new row, click the new +application link
Type Sample Note where it says -untitled, choose -Notes from the drop-down list, and -click New. +untitled, choose +Notes from the drop-down list, and +click New.
By mounting the package, we've caused all requests to - http://yourserver.test:8000/note - to be satisfied from the files at /web/service0/packages/samplenote/www.
It's time to document. For the tutorial we'll use + http://yourserver.test:8000/note + to be satisfied from the files at /web/service0/packages/samplenote/www.
It's time to document. For the tutorial we'll use pre-written documentation. When creating a package from scratch, start by copying the documentation template from - /web/openacs-dev/packages/acs-core-docs/xml/docs/xml/package-documentation-template.xml + /web/openacs-dev/packages/acs-core-docs/xml/docs/xml/package-documentation-template.xml to - yourpackage/www/docs/xml/index.xml.
You then edit that file with emacs to write the + yourpackage/www/docs/xml/index.xml.
You then edit that file with emacs to write the requirements and design sections, generate the html, and start coding. Store any supporting files, like page maps or schema - diagrams, in the www/doc/xml + diagrams, in the www/doc/xml directory, and store png or jpg versions of supporting files in the - www/doc directory.
For this tutorial, you should instead install the + www/doc directory.
For this tutorial, you should instead install the pre-written documentation files for the tutorial app. Log in - as service0, create the standard - directories, and copy the prepared documentation:
[service0@anthrax service0]$ cd /web/service0/packages/samplenote/ -[service0@anthrax samplenote]$ mkdir -p www/doc/xml -[service0@anthrax samplenote]$ cd www/doc/xml -[service0@anthrax xml]$ cp /web/service0/packages/acs-core-docs/www/files/samplenote/* . + as service0, create the standard + directories, and copy the prepared documentation:[service0@anthrax service0]$ cd /web/service0/packages/samplenote/ +[service0@anthrax samplenote]$ mkdir -p www/doc/xml +[service0@anthrax samplenote]$ cd www/doc/xml +[service0@anthrax xml]$ cp /web/service0/packages/acs-core-docs/www/files/samplenote/* . [service0@anthrax xml]$OpenACS uses DocBook for documentation. DocBook is an XML standard for semantic markup of documentation. That means that the tags you use indicate meaning, not intended appearance. The style sheet will determine appearance. You will edit the text in an xml file, and then process the file - into html for reading.
Open the file index.xml + into html for reading.
Open the file index.xml in emacs. Examine the file. Find the version history (look for the tag - <revhistory>). Add a + <revhistory>). Add a new record to the document version history. Look for the - <authorgroup> tag and + <authorgroup> tag and add yourself as a second author. Save and exit. For tips on - editing SGML files in emacs, see the section called “DocBook and Documentation”
Process the xml file to create html documentation. The + editing SGML files in emacs, see Section�, “DocBook and Documentation”
Process the xml file to create html documentation. The html documentation, including supporting files such as pictures, - is stored in the www/docs/ + is stored in the www/docs/ directory. A Makefile is provided to generate html from the xml, and copy all of the supporting files. If Docbook is set up correctly, all you need - to do is:
[service0@anthrax xml]$ make + to do is:[service0@anthrax xml]$ make cd .. ; /usr/bin/xsltproc ../../../acs-core-docs/www/xml/openacs.xsl xml/index.xml Writing requirements-introduction.html for sect1(requirements-introduction) Writing requirements-overview.html for sect1(requirements-overview) @@ -115,24 +115,24 @@ Writing bi01.html for bibliography Writing index.html for book [service0@yourserver xml]$Verify that the documentation was generated and reflects - your changes by browsing to http://yoursite:8000/samplenote/doc
Before you do any more work, make sure that your work is - protected by putting it all into cvs. The cvs + your changes by browsing to http://yoursite:8000/samplenote/doc
Before you do any more work, make sure that your work is + protected by putting it all into cvs. The cvs add command is not recursive, so you'll have to traverse the directory tree manually and add as you go. (More on - CVS)
[service0@yourserver xml]$ cd .. -[service0@yourserver doc]$ cd .. -[service0@yourserver www]$ cd .. -[service0@yourserver samplenote]$ cd .. -[service0@yourserver packages]$ cvs add samplenote/ + CVS)[service0@yourserver xml]$ cd .. +[service0@yourserver doc]$ cd .. +[service0@yourserver www]$ cd .. +[service0@yourserver samplenote]$ cd .. +[service0@yourserver packages]$ cvs add samplenote/ Directory /cvsroot/service0/packages/samplenote added to the repository -[service0@yourserver packages]$ cd samplenote/ -[service0@yourserver samplenote]$ cvs add www +[service0@yourserver packages]$ cd samplenote/ +[service0@yourserver samplenote]$ cvs add www Directory /cvsroot/service0/packages/samplenote/www added to the repository -[service0@yourserver samplenote]$ cd www -[service0@yourserver www]$ cvs add doc +[service0@yourserver samplenote]$ cd www +[service0@yourserver www]$ cvs add doc Directory /cvsroot/service0/packages/samplenote/www/doc added to the repository -[service0@yourserver www]$ cd doc -[service0@yourserver doc]$ cvs add * +[service0@yourserver www]$ cd doc +[service0@yourserver doc]$ cvs add * cvs add: cannot add special file `CVS'; skipping cvs add: scheduling file `admin-guide.html' for addition cvs add: scheduling file `bi01.html' for addition @@ -157,13 +157,13 @@ cvs add: scheduling file `user-interface.png' for addition Directory /cvsroot/service0/packages/samplenote/www/doc/xml added to the repository cvs add: use 'cvs commit' to add these files permanently -[service0@yourserver doc]$ cd xml -[service0@yourserver xml]$ cvs add Makefile index.xml +[service0@yourserver doc]$ cd xml +[service0@yourserver xml]$ cvs add Makefile index.xml cvs add: scheduling file `Makefile' for addition cvs add: scheduling file `index.xml' for addition cvs add: use 'cvs commit' to add these files permanently -[service0@yourserver xml]$ cd ../../.. -[service0@yourserver samplenote]$ cvs commit -m "new package" +[service0@yourserver xml]$ cd ../../.. +[service0@yourserver samplenote]$ cvs commit -m "new package" cvs commit: Examining . cvs commit: Examining www cvs commit: Examining www/doc Index: openacs-4/packages/acs-core-docs/www/tutorial-pages.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/tutorial-pages.html,v diff -u -r1.1.2.6 -r1.1.2.7 --- openacs-4/packages/acs-core-docs/www/tutorial-pages.html 4 May 2003 06:30:03 -0000 1.1.2.6 +++ openacs-4/packages/acs-core-docs/www/tutorial-pages.html 7 May 2003 17:40:59 -0000 1.1.2.7 @@ -1,18 +1,18 @@ -Creating Web Pages +
Creating Web Pages by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Each user-visible page in your package has, typically, - three parts. The xql file contains any database queries, the - tcl file holds the procedural logic for the page and does things +
Each user-visible page in your package has, typically, + three parts. The xql file contains any database queries, the + tcl file holds the procedural logic for the page and does things like check permissions, invoke the database queries, and modify - variables, and the adp page + variables, and the adp page holds html. The default page in any directory is - index, so we'll build that + index, so we'll build that first, starting with the tcl file: -
[service0@yourserver samplenote]$ cd /web/service0/packages/samplenote/www -[service0@yourserver www]$ emacs index.tclPaste this into the file.
ad_page_contract { +[service0@yourserver samplenote]$ cd /web/service0/packages/samplenote/www +[service0@yourserver www]$ emacs index.tclPaste this into the file.
ad_page_contract { This is the main page for the package. It displays all of the Notes and provides links to edit them and to create new Notes. @author rhs@mit.edu @@ -36,26 +36,26 @@ # construct an html table from the samplenotes database table set table_html [ad_table -Torderby $orderby notes_query { *SQL* } $table_def]There are several things to note about the file:
The page begins with an - ad_page_contract function. + ad_page_contract function. This is where we declare the input and output variables and their types and restrictions. It's also where we document the page, including descriptions of the parameters and return. (More information about TCL pages and page contracts)
We have one input variable, - orderby, which is optional - and defaults to title.
We have one output variable, table_html
We populate the table_html variable with a function call, ad_table, which does most of the work of generating an html table from a database recordset. We pass it several parameters:
- -Torderby $orderby
If the user has selected a column for sorting, this passes that information to the function.
- notes_query
This is the name of the SQL query that we'll put in the xql file.
- { *SQL* }
This is a dummy placeholder. It's possible to put sql directly in the tcl file, but this is deprecated because it's harder to make portable.
- $table_def
Here we pass in the variable we just constructed; it contains a list of column names and display titles.
Put the database query into a separate file. If the + orderby, which is optional + and defaults to title.
We have one output variable, table_html
We populate the table_html variable with a function call, ad_table, which does most of the work of generating an html table from a database recordset. We pass it several parameters:
- -Torderby $orderby
If the user has selected a column for sorting, this passes that information to the function.
- notes_query
This is the name of the SQL query that we'll put in the xql file.
- { *SQL* }
This is a dummy placeholder. It's possible to put sql directly in the tcl file, but this is deprecated because it's harder to make portable.
- $table_def
Here we pass in the variable we just constructed; it contains a list of column names and display titles.
Put the database query into a separate file. If the database query is exactly the same for Oracle and PostgreSQL, it can go into a file with the same name as the tcl file but an xql - extension, e.g., index.xql. If + extension, e.g., index.xql. If it is database-specific, it goes in - index-oracle.xql or - index-postgresql.xql. The + index-oracle.xql or + index-postgresql.xql. The format is the same in each case, an XML structure that contains - the SQL query. Create the file now.
[service0@yourserver www]$ emacs index.xqlNote that the - name parameter of the - fullquery tag exactly matches + the SQL query. Create the file now.
[service0@yourserver www]$ emacs index.xqlNote that the + name parameter of the + fullquery tag exactly matches the SQL query name specified in the - ad_table call. Also, the SQL query ends with a tcl function call that generates a SQL ORDER BY clause using several TCL variables.
<?xml version="1.0"?> + ad_table call. Also, the SQL query ends with a tcl function call that generates a SQL ORDER BY clause using several TCL variables.<?xml version="1.0"?> <queryset> <fullquery name="notes_query"> <querytext> @@ -66,20 +66,20 @@ [ad_order_by_from_sort_spec $orderby $table_def] </querytext> </fullquery> -</queryset>Create the user-visible page.
[service0@yourserver www]$ emacs index.adpThe first line indicates that this page should be rendered within the the master template, which defaults to /web/service0/www/default-master. The second line passes a title variable to the master template. The third line inserts the contents of the variable table_html. The last line is a link to a page we haven't created yet.
<master> +</queryset>Create the user-visible page.
[service0@yourserver www]$ emacs index.adpThe first line indicates that this page should be rendered within the the master template, which defaults to /web/service0/www/default-master. The second line passes a title variable to the master template. The third line inserts the contents of the variable table_html. The last line is a link to a page we haven't created yet.
<master> <property name="title">Sample Notes</property> @table_html@ -<p><a href="note-edit">Add a note</a></p>Before we can test these files, we have to notify the +<p><a href="note-edit">Add a note</a></p>
Before we can test these files, we have to notify the package manager that they exist. (More precisely, the tcl and adp will work fine as-is, but the xql file will not be - recognized until we tell the APM about it.).
Go to http://yourserver.test:8000/acs-admin/apm
Click on the samplenote link
Click Manage file information
Click Scan the packages/samplenote directory for additional files in thispackage
Click add checked files
On the list of files, on the - index.xql line, click - watch. Unlike adp and tcl + recognized until we tell the APM about it.).
Go to http://yourserver.test:8000/acs-admin/apm
Click on the samplenote link
Click Manage file information
Click Scan the packages/samplenote directory for additional files in thispackage
Click add checked files
On the list of files, on the + index.xql line, click + watch. Unlike adp and tcl pages, xql pages get cached. (And new xql files don't get loaded when they're added.) Watching an xql file causes the APM to load the contents of the XQL into memory so that it can be used, and to reload it whenever the file is changed. The - watch will last until the server is restarted.
Now that the pages are in the APM, check to make sure that the self-documenting code is working.
Browse to http://yourserver.test:8000/api-doc/
Click Notes 0.1d
Click Content Pages
Click index.tcl and examine the results.
Go to http://yourserver.test:8000/note/. You should see this:
+ watch will last until the server is restarted.Now that the pages are in the APM, check to make sure that the self-documenting code is working.
Browse to http://yourserver.test:8000/api-doc/
Click Notes 0.1d
Click Content Pages
Click index.tcl and examine the results.
Go to http://yourserver.test:8000/note/. You should see this:
Sample Notes Your Workspace : Main Site : Sample Note @@ -88,13 +88,13 @@ Add a note. foo@yourserver.test -Since our table is empty, it's a pretty boring page. So next we'll make it possible to add records.
If you get any other output, such as an error message, skip to the section called “Debugging and Automated Testing”.
We'll create a single page to handle both adding and +
Since our table is empty, it's a pretty boring page. So next we'll make it possible to add records.
If you get any other output, such as an error message, skip to Section�, “Debugging and Automated Testing”.
We'll create a single page to handle both adding and editing records. In this recursive approach, the same tcl function can present a blank HTML form, present the same form pre-loaded with an existing record, and handle the resulting submission of either updated or new records. This recursive approach reduces the total amount of code and files. First, - create the tcl:
[service0@yourserver www]$ emacs note-edit.tclPaste and save and edit:
ad_page_contract { + create the tcl:[service0@yourserver www]$ emacs note-edit.tclPaste and save and edit:
ad_page_contract { Simple add/edit form for samplenote. } { note_id:integer,optional @@ -120,7 +120,7 @@ db_dml do_update { *SQL* } } -after_submit { ad_returnredirect "index" -}We use ad_form +}
We use ad_form to automate most of the work here. Ad_form is a wrapper for the template functions for creating HTML forms. These functions should @@ -129,12 +129,12 @@ the appearance of forms.
The page takes a single, optional input parameter, note_id. If it's present, ad_form will assume that we're editing an existing record, look up that record, and pre-populate the - form. We'll also check and change the page title if necessary. We check user_id with ad_maybe_redirect_for_registration, + form. We'll also check and change the page title if necessary. We check user_id with ad_maybe_redirect_for_registration, which will redirect to the login page (with an automatic return path to bring them back after login or registration) if the visitor isn't logged in. Then we call ad_form, specifying the primary key of the table, the fields we want to edit, and - functions for insert and update.
Next, we create the database functions.
[service0@yourserver www]$ emacs note-edit.xql<?xml version="1.0"?> + functions for insert and update.Next, we create the database functions.
[service0@yourserver www]$ emacs note-edit.xql<?xml version="1.0"?> <queryset> <fullquery name="do_insert"> <querytext> @@ -157,17 +157,17 @@ where note_id = :note_id </querytext> </fullquery> -</queryset>Create the user-visible page:
[service0@yourserver www]$ emacs note-edit.adp<master> +</queryset>Create the user-visible page:
[service0@yourserver www]$ emacs note-edit.adp<master> <property name="title">@title@</property> <property name="context">{@title@}</property> <formtemplate id="note"></formtemplate>The property tags are passed to the master template, which uses their values to set the page title and context bar (breadcrumb trail). We use the same variable, - title, for both variables but + title, for both variables but wrap it in curly brackets for context so that the spaces aren't interpreted separators. The formtemplate tag outputs the form - html with the matching name.
Go to the APM as before and reload. Then test all this by going to the package home page and adding and editing a few records.
Put your new work into source control.
[service0@yourserver www]$ cvs add *.adp *.tcl *.xql + html with the matching name.Go to the APM as before and reload. Then test all this by going to the package home page and adding and editing a few records.
Put your new work into source control.
[service0@yourserver www]$ cvs add *.adp *.tcl *.xql cvs add: cannot add special file `CVS'; skipping cvs add: doc/CVS already exists cvs add: scheduling file `index.adp' for addition @@ -177,7 +177,7 @@ cvs add: scheduling file `note-edit.tcl' for addition cvs add: scheduling file `note-edit.xql' for addition cvs add: use 'cvs commit' to add these files permanently -[service0@yourserver www]$ cvs commit -m "new work" +[service0@yourserver www]$ cvs commit -m "new work" /cvsroot/service0/packages/samplenote/www/note-edit.xql~,v <-- note-edit.xql (many lines omitted) initial revision: 1.1 Index: openacs-4/packages/acs-core-docs/www/tutorial.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/tutorial.html,v diff -u -r1.1.2.4 -r1.1.2.5 --- openacs-4/packages/acs-core-docs/www/tutorial.html 29 Apr 2003 05:58:34 -0000 1.1.2.4 +++ openacs-4/packages/acs-core-docs/www/tutorial.html 7 May 2003 17:40:59 -0000 1.1.2.5 @@ -1,2 +1,2 @@ -Chapter�8.�Development Tutorial View comments on this page at openacs.org +Chapter�8.�Development Tutorial View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/unix-install.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/Attic/unix-install.html,v diff -u -r1.6.2.7 -r1.6.2.8 --- openacs-4/packages/acs-core-docs/www/unix-install.html 4 May 2003 06:30:03 -0000 1.6.2.7 +++ openacs-4/packages/acs-core-docs/www/unix-install.html 7 May 2003 17:40:59 -0000 1.6.2.8 @@ -1,2 +1,2 @@ -Chapter�3.�Installing on Unix/Linux View comments on this page at openacs.org +Chapter�3.�Installing on Unix/Linux View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/upgrade-detail.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/Attic/upgrade-detail.html,v diff -u -r1.3.2.3 -r1.3.2.4 --- openacs-4/packages/acs-core-docs/www/upgrade-detail.html 29 Apr 2003 05:58:34 -0000 1.3.2.3 +++ openacs-4/packages/acs-core-docs/www/upgrade-detail.html 7 May 2003 17:40:59 -0000 1.3.2.4 @@ -1,5 +1,5 @@ -Support for upgrades. +
Support for upgrades. by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. Index: openacs-4/packages/acs-core-docs/www/upgrade.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/upgrade.html,v diff -u -r1.3.2.3 -r1.3.2.4 --- openacs-4/packages/acs-core-docs/www/upgrade.html 29 Apr 2003 05:58:34 -0000 1.3.2.3 +++ openacs-4/packages/acs-core-docs/www/upgrade.html 7 May 2003 17:40:59 -0000 1.3.2.4 @@ -1,2 +1,2 @@ -Chapter�6.�Upgrading Table of Contents
View comments on this page at openacs.org +Chapter�6.�Upgrading Table of Contents
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/win-install.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/Attic/win-install.html,v diff -u -r1.8.2.6 -r1.8.2.7 --- openacs-4/packages/acs-core-docs/www/win-install.html 29 Apr 2003 05:58:34 -0000 1.8.2.6 +++ openacs-4/packages/acs-core-docs/www/win-install.html 7 May 2003 17:40:59 -0000 1.8.2.7 @@ -1,2 +1,2 @@ -Chapter�4.�Installing on Windows Table of Contents
View comments on this page at openacs.org +Chapter�4.�Installing on Windows Table of Contents
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/win2k-installation.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/win2k-installation.html,v diff -u -r1.8.2.8 -r1.8.2.9 --- openacs-4/packages/acs-core-docs/www/win2k-installation.html 4 May 2003 06:30:03 -0000 1.8.2.8 +++ openacs-4/packages/acs-core-docs/www/win2k-installation.html 7 May 2003 17:40:59 -0000 1.8.2.9 @@ -1,5 +1,5 @@ -OpenACS Installation Guide for Windows2000 Currently the best option to get OpenACS 4.6.3 running on Windows +
OpenACS Installation Guide for Windows2000 Currently the best option to get OpenACS 4.6.3 running on Windows is to use VMware and John Sequeira's Oasis VM distribution Index: openacs-4/packages/acs-core-docs/www/xml/kernel/permissions-design.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/xml/kernel/permissions-design.xml,v diff -u -r1.3.2.1 -r1.3.2.2 --- openacs-4/packages/acs-core-docs/www/xml/kernel/permissions-design.xml 7 May 2003 00:17:43 -0000 1.3.2.1 +++ openacs-4/packages/acs-core-docs/www/xml/kernel/permissions-design.xml 7 May 2003 17:41:02 -0000 1.3.2.2 @@ -207,11 +207,6 @@ more difficult, and as mentioned previously negatively impacts performance. -
These steps involve directly manipulating the -acs_methods , -acs_privileges , andacs_privilege_method_rules tables. A -web page for manipulating these features should be limited to site-wide -administrators."Modification of permissions." - involves fairly common operations. Users are typically able to administer permissions for objects they themselves create. The two basic operations here are