Gemstone - Produkt-Updates

<< Click to Display Table of Contents >>

Navigation:  Gemstone/S - Datenbank >

Gemstone - Produkt-Updates

Rechtzeitig anfangen

Wenn Gemtalk eine neue Version rausgibt, sollte man zügig ein Update seiner Anwendung ausprobieren, um mögliche Probleme rechtzeitig zu finden und zu lösen.

Das genaue Vorgehen wird in der Produktdokumentation beschrieben. Insgesamt ein gruseliges Vorgehen, also sollte man auch hier normieren bei der Entwicklung.

Erstaunlicherweise habe ich Systemklassen nie korrigiert, daher entfällt dieser Punkt bei meiner Kurzbeschreibung.

Beispiel

Ich habe nun eine Produktionsdatenbank ("es2025") in der Version 3.7.2 für ein Update fertig und möchte es auf die Version 3.7.5 updaten. Bei dem Upgrade soll die gleiche Softwareversion der eigenen Anwendung übernommen werden und natürlich die Daten.

Also bauen wir erst einmal eine neue Datenbank auf dem Rechner mit der Version 3.7.5, damit wir die passende Lizenz heraussuchen können und wir Gemstone/S in der Version 3.7.5 auf dem Rechner haben.

Neue Datenbank in der Version 3.7.5.

Also eine neue Datenbank anlegen:

 

createStone.solo update375 3.7.5 --registry=work --template=default_seaside

 

Wir sollten ggfs. danach eine ausreichende Lizenz plazieren, damit es bei der Übernahme der Daten keine Probleme gibt.

Stoppen aller beteiligten Datenbanken

Damit es keine Probleme gibt, sollte sichergestellt sein, daß keine der beiden Datenbanken laufen:

 

stopStone.solo update375 --registry=work

stopStone.solo es2025 --registry=work

 

Kopieren der RAW-Datenbankdaten in die Zieldatenbank

Wir kopieren nun den Inhalt der Produktdatenbank "es2025" in die 3.7.5 Datenbank:

 

cp /datadisk/pas/election/stones/es2025/extents/extent*.dbf /datadisk/pas/work/stones/update375/extents

 

Update geht los ...

Wir starten nun die Datenbank des Upgrade-Ziels:

 

startStone.solo update375 --registry=work

 

und schaffen uns eine Umgebung für die Basis-Skripte von Gemstone/S.

 

export GEMSTONE=/datadisk/pas/work/stones/update375/product

export PATH=$GEMSTONE/bin:$PATH

export upgradeLogDir=/tmp/

 

und führen das erste Skript aus im stones-Verzeichnis der Zieldatenbank:

 

$GEMSTONE/bin/upgradeImage -s update375

 

Dieser Schritt lädt den Basis 3.7.5 Code in die Datenbank. Danach muß noch der Seaside-Code aufgefrischt werden:

 

cd /datadisk/pas/work/stones/update375

$GEMSTONE/seaside/bin/upgradeSeasideImage -s update375 -P /datadisk/pas/git/GsDevKit_stones/bin/pas_upgrade.topaz

 

Und danach muß noch der gesamte Sourcecode der Anwendung selber geladen werden. Dazu geht man in das Verzeichnis mit den Applikationsspezifischen Skripten. In den "credentials.sh" muß noch der Stone-Name und die Registry angepasst werden. Die folgenden Aufrufe laden die notwendigen Codes für die Runtime und die Codes für die Anwendung.

 

# Hier liegen meine Anwendungsspezifische Daten und Skripte

cd ~/es2025/pas_python/unix-scrips

 

pas_load_pas_runtime.sh update375 work v100

./pas_load_appprereq.sh

./pas_load_appmodel.sh

./pas_load_appext.sh

 

und erhält dann einen lauffähigen Stone, der getestet werden kann. Dabei müssen die die Skripte pas_load_appprereq.sh, pas_load_appmodel.sh und pas_load_appext.sh in dem jeweiligen Projekt geschrieben werden.

Hier Beispiele, wie diese Skripte aussehen:

./pas_load_appprereq.sh

#

# Dieses Skript ist vielleicht nicht vorhanden bzw. leer. Es kann Arbeiten erledigen, die VOR dem Laden des Modelles notwendig sind

#

Allerdings könnten hier auch Pakete geladen werden, die in diesem System gebraucht werden und nicht Bestandteil der PAS-Runtime ist. Dazu zählt z.B.

Laden des PostgreSQL Connectors - pas_load_base_postgresql.sh

Laden des RabbitMQ Connectors - pas_load_base_rabbitmq.sh

Laden des PDF Paketes - pas_load_report4pdf.sh

Dann kommt noch das Skript zum Laden des Modelles:

./pas_load_appmodel.sh

#

# Dieses Skript lädt das Modell in die Datenbank. Das sollte normalerweise EIN Monticello-Paket sein (wenn auch groß). Alle notwendigen

# Informationen werden aus einer imaktuellen Verzeichnis befindlichen "credentials.sh" gelesen

#

##!/bin/bash
#
# This script loads all application source code needed for the webcati server
#
#
usage() {
 cat <<HELP
 
USAGE: $(basename $0)
Loads all core packages WITH the model definition
 
EXAMPLES
 $(basename $0)
 
HELP
}
 
GRPNAME=`id -n -g`
 
export INSTALL_HOME=`pwd`
 
if [ ! -f "./credentials.sh" ]; then
   echo "credentials.sh file not available"
   exit 4
fi
source ./credentials.sh
stoneName=$PAS_STONE_NAME
registryName=$PAS_STONE_REGISTRY
stonesDataHome=$STONES_DATA_HOME
 
# Extract the value of 'stone_dir' from the .ston file
stone_dir=$(pas_datadir.sh $stoneName $registryName $stonesDataHome)
# Check the return code of the script
if [[ $? -eq 0 ]]; then
   echo ""
else
   echo "The script failed with return code $?."
fi
# Check if stone_dir was found
if [[ -z "$stone_dir" ]]; then
   echo "Error: 'stone_dir' not found in $ston_file_path"
   exit 1
fi
source $stone_dir/customenv
if [ -s $GEMSTONE/seaside/etc/gemstone.secret ]; then
   . $GEMSTONE/seaside/etc/gemstone.secret
else
   echo 'Missing password file $GEMSTONE/seaside/etc/gemstone.secret'
   exit 1
fi
 
cd $INSTALL_HOME
 
cat << EOF | $GEMSTONE/bin/topaz -l -T 4000000
set user DataCurator pass $GEMSTONE_CURATOR_PASS gems $PAS_STONE_NAME
iferror where
login
run
| aSymbol names userProfile symbolDictionary |
aSymbol := #'${PAS_APP_DATA_CLASS}'.
userProfile := System myUserProfile.
names := userProfile symbolList names.
(names includes: aSymbol) ifFalse: [
       symbolDictionary := SymbolDictionary new name: aSymbol; yourself.
       userProfile insertDictionary: symbolDictionary at: names size + 1.
].
%
commit
doit
Gofer new
       url: '$PAS_APP_PACKAGES' ;
       package: '$PAS_APP_MDL_PACKAGE' ;
       load.
%
run
| aSymbol names userProfile symbolDictionary |
(symbolDictionary := System myUserProfile objectNamed: '${PAS_APP_DATA_CLASS}') isNil ifFalse:[
       (symbolDictionary includesKey: #'DataRootInstance') ifFalse: [
               | projectClass |
               (projectClass := System myUserProfile objectNamed: '${PAS_APP_PROJECT_CLASS}') isNil ifFalse:[
                       symbolDictionary at: #'DataRootInstance' put: projectClass new initialize
               ].
       ].
].
%
commit
EOF
 

 

Und zuletzt das Skript zum Laden der Logik (i.d.R. Extensions zu bereits bestehenden Klassen):

./pas_load_appmodel.sh

#

# Dieses Skript lädt das Modell in die Datenbank. Das sollte normalerweise EIN Monticello-Paket sein (wenn auch groß). Alle notwendigen

# Informationen werden aus einer imaktuellen Verzeichnis befindlichen "credentials.sh" gelesen

#

##!/bin/bash
#
# This script loads all application source code needed for the webcati server
#
#
usage() {
 cat <<HELP
 
USAGE: $(basename $0)
Loads all core packages WITH the model definition
 
EXAMPLES
 $(basename $0)
 
HELP
}
 
GRPNAME=`id -n -g`
 
export INSTALL_HOME=`pwd`
 
if [ ! -f "./credentials.sh" ]; then
   echo "credentials.sh file not available"
   exit 4
fi
source ./credentials.sh
stoneName=$PAS_STONE_NAME
registryName=$PAS_STONE_REGISTRY
stonesDataHome=$STONES_DATA_HOME
 
# Extract the value of 'stone_dir' from the .ston file
stone_dir=$(pas_datadir.sh $stoneName $registryName $stonesDataHome)
# Check the return code of the script
if [[ $? -eq 0 ]]; then
   echo ""
else
   echo "The script failed with return code $?."
fi
# Check if stone_dir was found
if [[ -z "$stone_dir" ]]; then
   echo "Error: 'stone_dir' not found in $ston_file_path"
   exit 1
fi
source $stone_dir/customenv
if [ -s $GEMSTONE/seaside/etc/gemstone.secret ]; then
   . $GEMSTONE/seaside/etc/gemstone.secret
else
   echo 'Missing password file $GEMSTONE/seaside/etc/gemstone.secret'
   exit 1
fi
 
cd $INSTALL_HOME
 
cat << EOF | $GEMSTONE/bin/topaz -l -T 4000000
set user DataCurator pass $GEMSTONE_CURATOR_PASS gems $PAS_STONE_NAME
iferror where
login
doit
Gofer new
       url: '$PAS_APP_PACKAGES' ;
       package: '$PAS_APP_EXT_PACKAGE' ;
       load.
%
doit
Gofer new
       url: '$PAS_APP_PACKAGES' ;
       package: 'ESystemV3Ext' ;
       load.
%
doit
Gofer new
       url: '$PAS_APP_PACKAGES' ;
       package: 'ESystemV3HouseKeeper' ;
       load.
%
doit
Gofer new
       url: '$PAS_APP_PACKAGES' ;
       package: 'ESystemV3Import' ;
       load.
%
doit
Gofer new
       url: '$PAS_APP_PACKAGES' ;
       package: 'ESystemV3REST' ;
       load.
%
commit
EOF