|
<< Click to Display Table of Contents >> Navigation: Gemstone/S - Datenbank > Gemstone - Produkt-Updates |
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.
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 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.
Damit es keine Probleme gibt, sollte sichergestellt sein, daß keine der beiden Datenbanken laufen:
stopStone.solo update375 --registry=work
stopStone.solo es2025 --registry=work
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
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