Some time ago I prepared some instructions for setting up GemStone on SliceHost.com. Since then some things have changed and I’ve had occasion to revisit the process and update my instructions. The following is mostly a script from which one can cut/paste various commands and does not have as much explanation as might be helpful for a beginner. The instructions should be useful for Ubuntu 9.10 (Karmic).

Obtain a slicehost account and (re)build it as Ubuntu 9.10 (Karmic). Add the IP address to your local hosts file as ‘slice’. When the slice is ready, log in the slice from your local machine and confirm the build:

ssh root@slice
cat /etc/lsb-release

Change your root password:

passwd

Configure the kernel so that it has more shared memory the next time it boots:

echo 'kernel.shmmax = 209715200 # 200 MB for GemStone' \
    >> /etc/sysctl.conf

Set up your timezone file (I am on the west coast of the United States):

mv /etc/localtime /etc/localtime.bak
ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime

Add ‘multiverse’ to sources so that we can get FastCGI:

mv /etc/apt/sources.list /etc/apt/sources.list.bak
cat /etc/apt/sources.list.bak | \
    sed s/universe/universe\ multiverse/ \
    >> /etc/apt/sources.list

Set the language and locale (I am in the United States):

locale-gen en_US.UTF-8
/usr/sbin/update-locale LANG=en_US.UTF-8

Update and upgrade the OS then install various additions, including Apache and FastCGI:

aptitude update
aptitude safe-upgrade
aptitude full-upgrade
aptitude install \
    build-essential bc zip ftp apache2 apache2.2-common \
    apache2-mpm-prefork apache2-utils libexpat1 ssl-cert \
    apache2-threaded-dev libapache2-mod-fastcgi

It seems that hosts is protected and we want to be able to read it:

chmod 644 /etc/hosts

GemStone needs a well-known port for access from client tools:

echo 'gs64ldi 50377/tcp # GemStone/S 64 Bit' >> /etc/services

Create a GemStone user with a new password (other fields are optional):

adduser glass

Configure sudo to allow full access to our new user:

echo 'glass ALL=(ALL) ALL' >> /etc/sudoers

Create and set ownership on the directory to hold the various GemStone files

mkdir /opt/gemstone
chown glass:glass /opt/gemstone

Define the GemStone site and enable some Apache modules:

echo "Include /opt/gemstone/etc/apache2.conf" \
    > /etc/apache2/sites-available/glass
a2enmod proxy_balancer
a2enmod proxy_http

On your local (client) machine generate RSA and DSS keys and print them:

cat ~/.ssh/*.pub

On the slice, add your local machine as an authorized source for login, replacing the strikeout text with the keys printed above:

mkdir /home/glass/.ssh
chown glass:glass /home/glass/.ssh
# use local machine's public key(s) on the following line
echo 'ssh- ...
' > /home/glass/.ssh/authorized_keys
chown glass:glass /home/glass/.ssh/authorized_keys
chmod 700 /home/glass/.ssh
chmod 600 /home/glass/.ssh/authorized_keys

Create an SSH configuration:

echo '
# added for GemStone
Port 30000
Protocol 2
PermitRootLogin no
PasswordAuthentication no
X11Forwarding no
UsePAM no
UseDNS no
AllowUsers glass' >> /etc/ssh/sshd_config

Create the firewall rules:

echo '*filter
# Allows all loopback (lo0) traffic
# and drop all traffic to 127/8 that does not use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allows all outbound traffic
# You can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allows HTTP and HTTPS connections from anywhere
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allows SSH connections
# THE -dport NUMBER IS THE SAME ONE YOU SET UP IN THE SSHD_CONFIG FILE
-A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT
# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# Allow GemStone connections
-A INPUT -p tcp --dport 8008 -j ACCEPT
-A INPUT -p tcp --dport 50377:50378 -j ACCEPT
# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Reject all other inbound
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT' > /etc/iptables.up.rules

Edit the network interface definitions to apply the firewall rules:

# add 'pre-up iptables-restore < /etc/iptables.up.rules'
# after 'iface lo inet loopback'
vim /etc/network/interfaces

Update the SSH settings:

/etc/init.d/ssh reload

On you local (client) machine login to the slice and see if you connect without a password:

ssh -p 30000 glass@slice

Back on the server, reboot the system:

reboot

On you local (client) machine login to the slice as the GemStone DBA:

ssh -p 30000 glass@slice

Back on the server, set up some environment variables and aliases:

echo '
# GemStone setup
export PS1="\[\e[0;35m\]\h\[\e[0;34m\] \w\[\e[00m\]$ "
export TZ=America/Los_Angeles
export GEMSTONE=/opt/gemstone/product
export PATH=/$GEMSTONE/bin:/$PATH
export GEMSTONE_NRS_ALL=#dir:/opt/gemstone#log:/opt/gemstone/log/%N_%P.log
export GEMSTONE_EXE_CONF=/opt/gemstone/etc
export GEMSTONE_LOG=/opt/gemstone/log/seaside.log
export GEMSTONE_SYS_CONF=/opt/gemstone/etc/system.conf
export GEMSTONE_LOGDIR=/opt/gemstone/log
export GEMSTONE_NAME=seaside
export GEMSTONE_DATADIR=/opt/gemstone/data
alias ll="ls -alF"
alias gslist="gslist -cvl"
alias startnetldi="startnetldi -g -a glass -p 50378:50378"
alias startFastCGI="\$GEMSTONE/seaside/bin/runSeasideGems start"
alias startHyper="\$GEMSTONE/seaside/bin/startSeaside_Hyper 8008"
alias stopFastCGI="\$GEMSTONE/seaside/bin/runSeasideGems stop"
alias stopstone="stopstone seaside DataCurator swordfish"
alias startstone="startstone seaside"
alias topaz="topaz -l -T 50000"
' >> ~/.bashrc

Now run the login script to get these values in your current session:

source ~/.bashrc

Now create the directories used by GemStone:

cd /opt/gemstone
mkdir data etc locks log www www/glass1 www/glass2 www/glass3

Download the GemStone product tree. The current version is 2.4.1 as of when this script was written. You should consider watching for later versions and updating the script as appropriate:

echo 'machine ftp.gemstone.com login anonymous password passwd' \
    >> ~/.netrc
ftp -p ftp.gemstone.com << EOF
cd /pub/GemStone64/2.4.1/
get GemStone64Bit2.4.1-x86_64.Linux.zip
bye
EOF

Unzip the product tree and copy some files:

unzip GemStone64Bit2.4.1-x86_64.Linux.zip
ln -s GemStone64Bit2.4.1-x86_64.Linux product
cp /opt/gemstone/product/data/system.conf /opt/gemstone/etc
cp /opt/gemstone/product/seaside/etc/gemstone.key /opt/gemstone/etc

Create a Stone configuration file:

echo '# configuration file for stone
DBF_EXTENT_NAMES = /opt/gemstone/data/extent0.dbf;
KEYFILE = /opt/gemstone/etc/gemstone.key;
STN_HALT_ON_FATAL_ERR = FALSE;
STN_TRAN_FULL_LOGGING = TRUE;
STN_TRAN_LOG_DIRECTORIES = /opt/gemstone/data/, /opt/gemstone/data/;
STN_TRAN_LOG_SIZES = 10000, 10000;
SHR_PAGE_CACHE_SIZE_KB = 75000;
' > /opt/gemstone/etc/seaside.conf

Create a Gem configuration file:

echo '# configuration file for gems
GEM_TEMPOBJ_CACHE_SIZE = 50000;
' > /opt/gemstone/etc/gem.conf

Obtain a fresh extent and allow read/write access to it:

cp /opt/gemstone/product/bin/extent0.seaside.dbf /opt/gemstone/data/extent0.dbf
chmod 600 /opt/gemstone/data/extent0.dbf

Create an Apache config file for GemStone:

echo '# Apache config file for GemStone/S FastCGI
ServerName glass
ServerAdmin webadmin@yourdomain.com
Listen 8081
Listen 8082
Listen 8083
FastCgiExternalServer /opt/gemstone/www/glass1/seaside \
    -host localhost:9001 -pass-header Authorization
FastCgiExternalServer /opt/gemstone/www/glass2/seaside \
    -host localhost:9002 -pass-header Authorization
FastCgiExternalServer /opt/gemstone/www/glass3/seaside \
    -host localhost:9003 -pass-header Authorization
<VirtualHost *:80>
    DocumentRoot /opt/gemstone/www
    CustomLog /opt/gemstone/log/glass-access.log combined
    ErrorLog /opt/gemstone/log/glass-error.log
    LogLevel info
    <Directory "/opt/gemstone/www">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
    <Proxy /seaside>
        AddDefaultCharset off
        Order allow,deny
        Allow from all
    </Proxy>
    ProxyPreserveHost On #make proxy rewrite urls in the output
    ProxyPass /seaside balancer://gemtrio
    ProxyPassReverse /seaside balancer://gemtrio
    <Proxy balancer://gemtrio>
        Order allow,deny
        Allow from all
        BalancerMember http://localhost:8081/seaside
        BalancerMember http://localhost:8082/seaside
        BalancerMember http://localhost:8083/seaside
    </Proxy>
</VirtualHost>
<VirtualHost *:8081>
    CustomLog /opt/gemstone/log/glass-vhost-8081-access.log combined
    ErrorLog /opt/gemstone/log/glass-vhost-8081-error.log
    LogLevel warn
    DocumentRoot /opt/gemstone/www/glass1
</VirtualHost>
<VirtualHost *:8082>
    CustomLog /opt/gemstone/log/glass-vhost-8082-access.log combined
    ErrorLog /opt/gemstone/log/glass-vhost-8082-error.log
    LogLevel warn
    DocumentRoot /opt/gemstone/www/glass2
</VirtualHost>
<VirtualHost *:8083>
    CustomLog /opt/gemstone/log/glass-vhost-8083-access.log combined
    ErrorLog /opt/gemstone/log/glass-vhost-8083-error.log
    LogLevel warn
    DocumentRoot /opt/gemstone/www/glass3
</VirtualHost>
' > /opt/gemstone/etc/apache2.conf

Create a home page:

echo '<html>
    <body>
        <h1>
            <a href="seaside">Seaside Rocks!</a>
        </h1>
    </body>
</html>' > /opt/gemstone/www/index.html

Disable the default site and enable the GemStone site:

sudo a2dissite 000-default
sudo a2ensite glass
sudo /etc/init.d/apache2 reload

Create an initialization file for Topaz:

cd
echo '! topaz initialization
set user DataCurator password swordfish gemstone seaside
login' > .topazini

Load the latest version of FastCGI to get a fix for a content-length bug:

topaz << EOF
run
| repository name version |
repository := MCHttpRepository
    location: 'http://seaside.gemstone.com/ss/fastcgi'
    user: ''
    password: ''.
name := repository allFileNames at: 2.
version := repository loadVersionFromFileNamed: name.
version load.
%
commit
logout
exit
EOF

At this point you should be able to start GemStone:

startnetldi
startstone
startFastCGI

Now you can navigate to your slice and Seaside should be running!