From 92498b32bfb6ea764782d891dda914de411a69b6 Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Thu, 11 Apr 2013 15:27:27 -0400
Subject: [PATCH] Tracking upgrade using existing config files.

The upgrade framework has been modified to use pki.conf to track
system upgrade, tomcat.conf to track instance upgrade, and CS.cfg
to track subsystem upgrade.

The preop.product.version in CS.cfg has been renamed into
product.version and is now used to track upgrade.

Ticket #544
---
 base/VERSION                                       |  4 +-
 base/ca/shared/conf/CS.cfg.in                      |  2 +-
 base/common/python/pki/upgrade.py                  | 80 ++++++++++++++--------
 base/common/shared/conf/tomcat.conf                |  2 +
 .../netscape/cms/servlet/csadmin/WelcomePanel.java |  2 +-
 base/kra/shared/conf/CS.cfg.in                     |  2 +-
 base/ocsp/shared/conf/CS.cfg.in                    |  2 +-
 base/ra/doc/CS.cfg.in                              |  2 +-
 base/ra/lib/perl/PKI/RA/wizard.pm                  |  2 +-
 base/server/config/pkislots.cfg                    |  1 +
 base/server/etc/pki.conf                           |  2 +
 base/server/src/engine/pkiparser.py                |  7 +-
 base/tks/shared/conf/CS.cfg.in                     |  2 +-
 base/tps/doc/CS.cfg.in                             |  2 +-
 base/tps/lib/perl/PKI/TPS/wizard.pm                |  2 +-
 15 files changed, 73 insertions(+), 41 deletions(-)

diff --git a/base/VERSION b/base/VERSION
index 066f31138a9787b79943d349a713c4ee0a30c5c5..ba3b34fa869c06682f04ff713715e9df47c725ab 100644
--- a/base/VERSION
+++ b/base/VERSION
@@ -1,3 +1,3 @@
 Name: pki
-Specification-Version: ${APPLICATION_VERSION}
-Implementation-Version: ${VERSION}
+Specification-Version: ${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}
+Implementation-Version: ${APPLICATION_VERSION}
diff --git a/base/ca/shared/conf/CS.cfg.in b/base/ca/shared/conf/CS.cfg.in
index 8e6dd0a1d9b9c61db76ec7f55a58071c09addd28..430e4802c4d851587cb93bfdd8d90d163b571ad5 100644
--- a/base/ca/shared/conf/CS.cfg.in
+++ b/base/ca/shared/conf/CS.cfg.in
@@ -18,7 +18,7 @@ pkiremove.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
 installDate=[INSTALL_TIME]
 preop.wizard.name=CA Setup Wizard
 preop.product.name=CS
-preop.product.version=@APPLICATION_VERSION@
+product.version=@APPLICATION_VERSION@
 preop.system.name=CA
 preop.system.fullname=Certificate Authority
 proxy.securePort=[PKI_PROXY_SECURE_PORT]
diff --git a/base/common/python/pki/upgrade.py b/base/common/python/pki/upgrade.py
index 65d03da9b8178828bae6b74824af8c2a2fbd0279..48fc7b834401b97d7ab36a69cbb18109f9017932 100644
--- a/base/common/python/pki/upgrade.py
+++ b/base/common/python/pki/upgrade.py
@@ -32,20 +32,17 @@ import pki
 
 DEFAULT_VERSION   = '10.0.0'
 
-VERSION_KEY       = 'Configuration-Version'
-INDEX_KEY         = 'Scriptlet-Index'
-
 UPGRADE_DIR       = pki.SHARE_DIR + '/server/upgrade'
 VERSION_DIR       = UPGRADE_DIR + '/%s'
 SCRIPTLET_FILE    = VERSION_DIR + '/%s'
 
-SYSTEM_VERSION    = pki.CONF_DIR + '/' + pki.VERSION_FILE
+SYSTEM_TRACKER    = pki.CONF_DIR + '/pki.conf'
 
 INSTANCE_CONF     = pki.CONF_DIR + '/%s'
-INSTANCE_VERSION  = INSTANCE_CONF + '/' + pki.VERSION_FILE
+INSTANCE_TRACKER  = INSTANCE_CONF + '/tomcat.conf'
 
 SUBSYSTEM_CONF    = INSTANCE_CONF + '/%s'
-SUBSYSTEM_VERSION = SUBSYSTEM_CONF + '/' + pki.VERSION_FILE
+SUBSYSTEM_TRACKER = SUBSYSTEM_CONF + '/CS.cfg'
 
 verbose           = False
 
@@ -128,10 +125,18 @@ class PKIUpgradeException(Exception):
 
 class PKIUpgradeTracker(object):
 
-    def __init__(self, name, filename):
+    def __init__(self, name, filename,
+        delimiter=':',
+        version_key='Configuration-Version',
+        index_key='Scriptlet-Index'):
+
         self.name = name
         self.filename = filename
 
+        self.delimiter = delimiter
+        self.version_key = version_key
+        self.index_key = index_key
+
         self.read()
 
 
@@ -161,17 +166,17 @@ class PKIUpgradeTracker(object):
 
         print 'Removing ' + self.name + ' tracker.'
 
-        if os.path.exists(self.filename):
-            if verbose: print 'Removing ' + self.filename
-            os.remove(self.filename)
+        self.remove_version()
+        self.remove_index()
+        self.write()
 
 
     def reset(self, version):
 
         print 'Resetting ' + self.name + ' tracker.'
 
-        self.lines = []
         self.set_version(version)
+        self.remove_index()
         self.write()
 
 
@@ -179,8 +184,12 @@ class PKIUpgradeTracker(object):
 
         print self.name + ':'
 
-        for line in self.lines:
-            print '  ' + line
+        version = self.get_version()
+        print '  Configuration version: ' + str(version)
+
+        index = self.get_index()
+        if index > 0:
+            print '  Last completed scriptlet: ' + str(index)
 
         print
 
@@ -191,8 +200,8 @@ class PKIUpgradeTracker(object):
 
         for line in self.lines:
 
-            # parse <key>: <value>
-            match = re.match('^\s*(\S*)\s*:\s*(.*)\s*$', line)
+            # parse <key> <delimiter> <value>
+            match = re.match('^\s*(\S*)\s*%s\s*(.*)\s*$' % self.delimiter, line)
 
             if not match:
                 continue
@@ -213,8 +222,8 @@ class PKIUpgradeTracker(object):
 
         for index, line in enumerate(self.lines):
 
-            # parse <key>: <value>
-            match = re.match('^\s*(\S*)\s*:\s*(.*)\s*$', line)
+            # parse <key> <delimiter> <value>
+            match = re.match('^\s*(\S*)\s*%s\s*(.*)\s*$' % self.delimiter, line)
 
             if not match:
                 continue
@@ -224,20 +233,20 @@ class PKIUpgradeTracker(object):
             if key.lower() != name.lower():
                 continue
 
-            self.lines[index] = key + ': ' + value
+            self.lines[index] = key + self.delimiter + value
             found = True
             break
 
         if not found:
-            self.lines.append(name + ': ' + value)
+            self.lines.append(name + self.delimiter + value)
 
 
     def remove_property(self, name):
 
         for index, line in enumerate(self.lines):
 
-            # parse <key>: <value>
-            match = re.match('^\s*(\S*)\s*: \s*(.*)\s*$', line)
+            # parse <key> <delimiter> <value>
+            match = re.match('^\s*(\S*)\s*%s\s*(.*)\s*$' % self.delimiter, line)
 
             if not match:
                 continue
@@ -252,7 +261,7 @@ class PKIUpgradeTracker(object):
 
     def get_index(self):
 
-        index = self.get_property(INDEX_KEY)
+        index = self.get_property(self.index_key)
 
         if index:
             return int(index)
@@ -261,16 +270,16 @@ class PKIUpgradeTracker(object):
 
 
     def set_index(self, index):
-        self.set_property(INDEX_KEY, str(index))
+        self.set_property(self.index_key, str(index))
 
 
     def remove_index(self):
-        self.remove_property(INDEX_KEY)
+        self.remove_property(self.index_key)
 
 
     def get_version(self):
 
-        version = self.get_property(VERSION_KEY)
+        version = self.get_property(self.version_key)
 
         if version:
             return Version(version)
@@ -279,7 +288,11 @@ class PKIUpgradeTracker(object):
 
 
     def set_version(self, version):
-        self.set_property(VERSION_KEY, str(version))
+        self.set_property(self.version_key, str(version))
+
+
+    def remove_version(self):
+        self.remove_property(self.version_key)
 
 
 @functools.total_ordering
@@ -603,7 +616,10 @@ class PKIUpgrader():
                 tracker = self.subsystem_trackers[instance]
             except KeyError:
                 tracker = PKIUpgradeTracker(name + ' subsystem',
-                    SUBSYSTEM_VERSION % (instance, subsystem))
+                    SUBSYSTEM_TRACKER % (instance, subsystem),
+                    delimiter='=',
+                    version_key='product.version',
+                    index_key='upgrade.index')
                 self.subsystem_trackers[name] = tracker
 
         elif instance:
@@ -611,14 +627,20 @@ class PKIUpgrader():
                 tracker = self.instance_trackers[instance]
             except KeyError:
                 tracker = PKIUpgradeTracker(instance + ' instance',
-                    INSTANCE_VERSION % instance)
+                    INSTANCE_TRACKER % instance,
+                    delimiter='=',
+                    version_key='PKI_VERSION',
+                    index_key='PKI_UPGRADE_INDEX')
                 self.instance_trackers[instance] = tracker
 
         else:
             if self.system_tracker:
                 tracker = self.system_tracker
             else:
-                tracker = PKIUpgradeTracker('system', SYSTEM_VERSION)
+                tracker = PKIUpgradeTracker('system', SYSTEM_TRACKER,
+                    delimiter='=',
+                    version_key='PKI_VERSION',
+                    index_key='PKI_UPGRADE_INDEX')
                 self.system_tracker = tracker
 
         return tracker
diff --git a/base/common/shared/conf/tomcat.conf b/base/common/shared/conf/tomcat.conf
index 57a3d15097a70bfc950d8936e8d53e4dfd39f0c6..9457b0ce73d1beddd92148e5770de510f0cc63d1 100644
--- a/base/common/shared/conf/tomcat.conf
+++ b/base/common/shared/conf/tomcat.conf
@@ -62,3 +62,5 @@ TOMCAT_LOG="[TOMCAT_LOG_DIR]/tomcat-initd.log"
 # If you wish to further customize your tomcat environment,
 # put your own definitions here
 # (i.e. LD_LIBRARY_PATH for some jdbc drivers)
+
+PKI_VERSION=[APPLICATION_VERSION]
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java
index 4224c4ebfdf8c19d149f047aa3c9440bb1b067b0..6a0df1e2fae776f4a399f98ec166cf788ba2c295 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java
@@ -90,7 +90,7 @@ public class WelcomePanel extends WizardPanelBase {
             context.put("productname",
                     cs.getString("preop.product.name"));
             context.put("productversion",
-                    cs.getString("preop.product.version"));
+                    cs.getString("product.version"));
         } catch (EBaseException e) {
         }
         context.put("panel", "admin/console/config/welcomepanel.vm");
diff --git a/base/kra/shared/conf/CS.cfg.in b/base/kra/shared/conf/CS.cfg.in
index 56436841384767d0216adb0ee6ced9f57979b70e..cf5abab1ec19d3b2ad05a44992374b51c450b96d 100644
--- a/base/kra/shared/conf/CS.cfg.in
+++ b/base/kra/shared/conf/CS.cfg.in
@@ -17,7 +17,7 @@ pkiremove.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
 installDate=[INSTALL_TIME]
 preop.wizard.name=DRM Setup Wizard
 preop.product.name=CS
-preop.product.version=@APPLICATION_VERSION@
+product.version=@APPLICATION_VERSION@
 preop.system.name=DRM
 preop.system.fullname=Data Recovery Manager
 proxy.securePort=[PKI_PROXY_SECURE_PORT]
diff --git a/base/ocsp/shared/conf/CS.cfg.in b/base/ocsp/shared/conf/CS.cfg.in
index 3a1e6c6606bca6ed92eb18bc387eee531f97ac75..9c7bd66ec11691ccfcc2542e67673643bb74d026 100644
--- a/base/ocsp/shared/conf/CS.cfg.in
+++ b/base/ocsp/shared/conf/CS.cfg.in
@@ -25,7 +25,7 @@ preop.admincert.profile=caAdminCert
 preop.securitydomain.admin_url=https://[PKI_MACHINE_NAME]:9445
 preop.wizard.name=OCSP Setup Wizard
 preop.product.name=CS
-preop.product.version=@APPLICATION_VERSION@
+product.version=@APPLICATION_VERSION@
 preop.system.name=OCSP
 preop.system.fullname=OCSP Responder
 proxy.securePort=[PKI_PROXY_SECURE_PORT]
diff --git a/base/ra/doc/CS.cfg.in b/base/ra/doc/CS.cfg.in
index 7e4b677f29a10b1ed4f544b445713cde4eed8fa7..65b1cda94ad7dfa7897799b74488b4e4f91df087 100644
--- a/base/ra/doc/CS.cfg.in
+++ b/base/ra/doc/CS.cfg.in
@@ -190,7 +190,7 @@ conn.ca1.timeout=100
 conn.ca1.SSLOn=true
 conn.ca1.keepAlive=true
 preop.pin=[PKI_RANDOM_NUMBER]
-preop.product.version=@APPLICATION_VERSION@
+product.version=@APPLICATION_VERSION@
 preop.cert._000=#########################################
 preop.cert._001=# Installation configuration "preop" certs parameters
 preop.cert._002=#########################################
diff --git a/base/ra/lib/perl/PKI/RA/wizard.pm b/base/ra/lib/perl/PKI/RA/wizard.pm
index 5fe1e7536f49813ef3ad07ebaf4c1ae72308e53a..71b011b2ee9adc7ef31c62e4c38218faa54b327c 100755
--- a/base/ra/lib/perl/PKI/RA/wizard.pm
+++ b/base/ra/lib/perl/PKI/RA/wizard.pm
@@ -290,7 +290,7 @@ sub render_panel
     }
     $symbol{p}        = $panelnum;
     $symbol{subpanelno}        = $panelnum+1;
-    $symbol{productversion}    =  $::config->get("preop.product.version");
+    $symbol{productversion}    =  $::config->get("product.version");
     $symbol{csstate}        = "1";
 
 #    $symbol{urls}        = [ "cert1", "cert2" ];  #createsubsystem
diff --git a/base/server/config/pkislots.cfg b/base/server/config/pkislots.cfg
index 1cb463bfed6419420b019a794c28e603c123d960..a2a661f24e51d627d6727ad47dacda7417c643f5 100644
--- a/base/server/config/pkislots.cfg
+++ b/base/server/config/pkislots.cfg
@@ -28,6 +28,7 @@ SYSTEM_USER_LIBRARIES_SLOT=[SYSTEM_USER_LIBRARIES]
 TMP_DIR_SLOT=[TMP_DIR]
 TPS_DIR_SLOT=[TPS_DIR]
 [Tomcat]
+application_version=[APPLICATION_VERSION]
 INSTALL_TIME_SLOT=[INSTALL_TIME]
 PKI_ADMIN_SECURE_PORT_SLOT=[PKI_ADMIN_SECURE_PORT]
 PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME_SLOT=[PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME]
diff --git a/base/server/etc/pki.conf b/base/server/etc/pki.conf
index 24decec523bed258741e8f3869773c1c75f69c0b..c7f4f8470e7efe81d61d4714445e0db035f0909e 100644
--- a/base/server/etc/pki.conf
+++ b/base/server/etc/pki.conf
@@ -2,3 +2,5 @@
 RESTEASY_LIB=${RESTEASY_LIB}
 # JNI jar file location
 JNI_JAR_DIR=${JNI_JAR_DIR}
+
+PKI_VERSION=${APPLICATION_VERSION}
diff --git a/base/server/src/engine/pkiparser.py b/base/server/src/engine/pkiparser.py
index 047e8614eeb6d5a9f3e1ceaeb631738ae86fae74..8fcac77ca34b9fdfe5fa18b60de52233c38e5e87 100644
--- a/base/server/src/engine/pkiparser.py
+++ b/base/server/src/engine/pkiparser.py
@@ -33,7 +33,9 @@ import sys
 import time
 
 
-# PKI Deployment Imports
+# PKI Imports
+import pki
+import pki.upgrade
 import pkilogging
 import pkiconfig as config
 import pkimessages as log
@@ -180,7 +182,10 @@ class PKIConfigParser:
             default_http_port = '80'
             default_https_port = '443'
 
+        application_version = str(pki.upgrade.Version(pki.implementation_version()))
+
         self.pki_config = ConfigParser.SafeConfigParser({
+            'application_version': application_version,
             'pki_instance_name': default_instance_name,
             'pki_http_port': default_http_port,
             'pki_https_port': default_https_port,
diff --git a/base/tks/shared/conf/CS.cfg.in b/base/tks/shared/conf/CS.cfg.in
index da604d175eda632ef2917557a7fe90af90617031..90679ccc5b9322b75787c2f1cc92bf437ff4f595 100644
--- a/base/tks/shared/conf/CS.cfg.in
+++ b/base/tks/shared/conf/CS.cfg.in
@@ -25,7 +25,7 @@ preop.securitydomain.admin_url=https://[PKI_MACHINE_NAME]:9445
 preop.wizard.name=TKS Setup Wizard
 preop.system.name=TKS
 preop.product.name=CS
-preop.product.version=@APPLICATION_VERSION@
+product.version=@APPLICATION_VERSION@
 preop.system.fullname=Token Key Service
 proxy.securePort=[PKI_PROXY_SECURE_PORT]
 proxy.unsecurePort=[PKI_PROXY_UNSECURE_PORT]
diff --git a/base/tps/doc/CS.cfg.in b/base/tps/doc/CS.cfg.in
index 1c7e26877a1cce9819e35bc7cc453f256cf92fe2..186e5f7e1b6c4014932f98fbf38d0f43c8f29e4f 100644
--- a/base/tps/doc/CS.cfg.in
+++ b/base/tps/doc/CS.cfg.in
@@ -370,7 +370,7 @@ channel.defKeyIndex=0
 #            * channel.appletMemorySize=5000
 #
 preop.pin=[PKI_RANDOM_NUMBER]
-preop.product.version=@APPLICATION_VERSION@
+product.version=@APPLICATION_VERSION@
 preop.cert._000=#########################################
 preop.cert._001=# Installation configuration "preop" certs parameters
 preop.cert._002=#########################################
diff --git a/base/tps/lib/perl/PKI/TPS/wizard.pm b/base/tps/lib/perl/PKI/TPS/wizard.pm
index db8b26526624468e90471a4f92a31e62e5002aac..af1689acc46893c515b202999e302d2e72916e59 100755
--- a/base/tps/lib/perl/PKI/TPS/wizard.pm
+++ b/base/tps/lib/perl/PKI/TPS/wizard.pm
@@ -296,7 +296,7 @@ sub render_panel
     }
     $symbol{p}        = $panelnum;
     $symbol{subpanelno}        = $panelnum+1;
-    $symbol{productversion}    =  $::config->get("preop.product.version");
+    $symbol{productversion}    =  $::config->get("product.version");
     $symbol{csstate}        = "1";
 
 #    $symbol{urls}        = [ "cert1", "cert2" ];  #createsubsystem
-- 
1.8.1.4

