>From 96ed77fefd73b948894036b596d26233a7e12c20 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 27 Nov 2013 11:53:57 -0500
Subject: [PATCH 232/234] Moved web application context file.

The location of web application context file has been changed from
  <instance>/webapps/<name>/META-INF/context.xml
into
  <instance>/conf/Catalina/localhost/<name>.xml.
This will eventually allow deploying the web application directly
from the shared folder.

A new upgrade script has been added to move the context files in
the existing instances.

Ticket #499
---
 .../context.xml => conf/Catalina/localhost/ca.xml} |  0
 base/ca/shared/conf/context.xml                    | 40 ---------
 base/common/python/pki/util.py                     | 15 ++++
 base/common/upgrade/10.1.0/.gitignore              |  4 +
 base/common/upgrade/10.1.99/.gitignore             |  4 +
 .../Catalina/localhost/kra.xml}                    |  0
 base/kra/shared/conf/context.xml                   | 40 ---------
 .../Catalina/localhost/ocsp.xml}                   |  0
 base/ocsp/shared/conf/context.xml                  | 40 ---------
 base/server/etc/default.cfg                        |  3 -
 .../deployment/scriptlets/instance_layout.py       | 69 +++++++++++-----
 .../deployment/scriptlets/webapp_deployment.py     | 96 +++++++---------------
 .../Catalina/localhost/ROOT.xml}                   |  0
 .../Catalina/localhost/pki.xml}                    |  0
 base/server/upgrade/10.0.99/04-FixLogFileOwnership | 12 +--
 base/server/upgrade/10.1.0/.gitignore              |  4 +
 .../10.1.99/01-MoveWebApplicationContextFile       | 96 ++++++++++++++++++++++
 .../Catalina/localhost/tks.xml}                    |  0
 base/tks/shared/conf/context.xml                   | 40 ---------
 .../Catalina/localhost/tps.xml}                    |  0
 base/tps-tomcat/shared/conf/context.xml            | 40 ---------
 21 files changed, 203 insertions(+), 300 deletions(-)
 rename base/ca/shared/{webapps/ca/META-INF/context.xml => conf/Catalina/localhost/ca.xml} (100%)
 delete mode 100644 base/ca/shared/conf/context.xml
 create mode 100644 base/common/upgrade/10.1.0/.gitignore
 create mode 100644 base/common/upgrade/10.1.99/.gitignore
 rename base/kra/shared/{webapps/kra/META-INF/context.xml => conf/Catalina/localhost/kra.xml} (100%)
 delete mode 100644 base/kra/shared/conf/context.xml
 rename base/ocsp/shared/{webapps/ocsp/META-INF/context.xml => conf/Catalina/localhost/ocsp.xml} (100%)
 delete mode 100644 base/ocsp/shared/conf/context.xml
 rename base/server/share/{webapps/ROOT/META-INF/context.xml => conf/Catalina/localhost/ROOT.xml} (100%)
 rename base/server/share/{webapps/pki/META-INF/context.xml => conf/Catalina/localhost/pki.xml} (100%)
 create mode 100644 base/server/upgrade/10.1.0/.gitignore
 create mode 100755 base/server/upgrade/10.1.99/01-MoveWebApplicationContextFile
 rename base/tks/shared/{webapps/tks/META-INF/context.xml => conf/Catalina/localhost/tks.xml} (100%)
 delete mode 100644 base/tks/shared/conf/context.xml
 rename base/tps-tomcat/shared/{webapps/tps/META-INF/context.xml => conf/Catalina/localhost/tps.xml} (100%)
 delete mode 100644 base/tps-tomcat/shared/conf/context.xml

diff --git a/base/ca/shared/webapps/ca/META-INF/context.xml b/base/ca/shared/conf/Catalina/localhost/ca.xml
similarity index 100%
rename from base/ca/shared/webapps/ca/META-INF/context.xml
rename to base/ca/shared/conf/Catalina/localhost/ca.xml
diff --git a/base/ca/shared/conf/context.xml b/base/ca/shared/conf/context.xml
deleted file mode 100644
index 8b6fe490589481ed09a2e08cbd46004a0a1156df..0000000000000000000000000000000000000000
--- a/base/ca/shared/conf/context.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<!-- BEGIN COPYRIGHT BLOCK
-     Copyright (C) 2006-2010 Red Hat, Inc.
-     All rights reserved.
-     Modifications: configuration parameters
-     END COPYRIGHT BLOCK -->
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<!-- The contents of this file will be loaded for each web application -->
-<Context crossContext="true" allowLinking="true">
-
-    <!-- Default set of monitored resources -->
-    <WatchedResource>WEB-INF/web.xml</WatchedResource>
-	
-    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
-    <!--
-    <Manager pathname="" />
-    -->
-
-    <!-- Uncomment this to enable Comet connection tacking (provides events
-         on session expiration as well as webapp lifecycle) -->
-    <!--
-    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-    -->
-
-</Context>
diff --git a/base/common/python/pki/util.py b/base/common/python/pki/util.py
index 62aec2c475b4e94fc135a9a64a87e69864468864..a0481852d9606cd5230ddc8043ae90d940450cc5 100644
--- a/base/common/python/pki/util.py
+++ b/base/common/python/pki/util.py
@@ -97,3 +97,18 @@ def copydirs(source, dest):
     os.utime(dest, (st.st_atime, st.st_mtime))
     os.chmod(dest, st.st_mode)
     os.chown(dest, st.st_uid, st.st_gid)
+
+def chown(path, uid, gid):
+    """
+    Change ownership of a folder and its contents.
+    """
+
+    os.chown(path, uid, gid)
+
+    for item in os.listdir(path):
+        itempath = os.path.join(path, item)
+
+        if os.path.isfile(itempath):
+            os.chown(itempath, uid, gid)
+        elif os.path.isdir(itempath):
+            chown(itempath, uid, gid)
diff --git a/base/common/upgrade/10.1.0/.gitignore b/base/common/upgrade/10.1.0/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..5e7d2734cfc60289debf74293817c0a8f572ff32
--- /dev/null
+++ b/base/common/upgrade/10.1.0/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/base/common/upgrade/10.1.99/.gitignore b/base/common/upgrade/10.1.99/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..5e7d2734cfc60289debf74293817c0a8f572ff32
--- /dev/null
+++ b/base/common/upgrade/10.1.99/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/base/kra/shared/webapps/kra/META-INF/context.xml b/base/kra/shared/conf/Catalina/localhost/kra.xml
similarity index 100%
rename from base/kra/shared/webapps/kra/META-INF/context.xml
rename to base/kra/shared/conf/Catalina/localhost/kra.xml
diff --git a/base/kra/shared/conf/context.xml b/base/kra/shared/conf/context.xml
deleted file mode 100644
index 8b6fe490589481ed09a2e08cbd46004a0a1156df..0000000000000000000000000000000000000000
--- a/base/kra/shared/conf/context.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<!-- BEGIN COPYRIGHT BLOCK
-     Copyright (C) 2006-2010 Red Hat, Inc.
-     All rights reserved.
-     Modifications: configuration parameters
-     END COPYRIGHT BLOCK -->
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<!-- The contents of this file will be loaded for each web application -->
-<Context crossContext="true" allowLinking="true">
-
-    <!-- Default set of monitored resources -->
-    <WatchedResource>WEB-INF/web.xml</WatchedResource>
-	
-    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
-    <!--
-    <Manager pathname="" />
-    -->
-
-    <!-- Uncomment this to enable Comet connection tacking (provides events
-         on session expiration as well as webapp lifecycle) -->
-    <!--
-    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-    -->
-
-</Context>
diff --git a/base/ocsp/shared/webapps/ocsp/META-INF/context.xml b/base/ocsp/shared/conf/Catalina/localhost/ocsp.xml
similarity index 100%
rename from base/ocsp/shared/webapps/ocsp/META-INF/context.xml
rename to base/ocsp/shared/conf/Catalina/localhost/ocsp.xml
diff --git a/base/ocsp/shared/conf/context.xml b/base/ocsp/shared/conf/context.xml
deleted file mode 100644
index 8b6fe490589481ed09a2e08cbd46004a0a1156df..0000000000000000000000000000000000000000
--- a/base/ocsp/shared/conf/context.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<!-- BEGIN COPYRIGHT BLOCK
-     Copyright (C) 2006-2010 Red Hat, Inc.
-     All rights reserved.
-     Modifications: configuration parameters
-     END COPYRIGHT BLOCK -->
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<!-- The contents of this file will be loaded for each web application -->
-<Context crossContext="true" allowLinking="true">
-
-    <!-- Default set of monitored resources -->
-    <WatchedResource>WEB-INF/web.xml</WatchedResource>
-	
-    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
-    <!--
-    <Manager pathname="" />
-    -->
-
-    <!-- Uncomment this to enable Comet connection tacking (provides events
-         on session expiration as well as webapp lifecycle) -->
-    <!--
-    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-    -->
-
-</Context>
diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg
index b83fb144d2913437178b44984b60d749d0005490..94d34b20163239195592aeae2b816cc408f2c4e2 100644
--- a/base/server/etc/default.cfg
+++ b/base/server/etc/default.cfg
@@ -244,9 +244,6 @@ pki_tomcat_common_path=%(pki_instance_path)s/common
 pki_tomcat_common_lib_path=%(pki_tomcat_common_path)s/lib
 pki_tomcat_tmpdir_path=%(pki_instance_path)s/temp
 pki_tomcat_webapps_path=%(pki_instance_path)s/webapps
-pki_tomcat_webapps_root_path=%(pki_tomcat_webapps_path)s/ROOT
-pki_tomcat_webapps_common_path=%(pki_tomcat_webapps_path)s/pki
-pki_tomcat_webapps_root_webinf_path=%(pki_tomcat_webapps_root_path)s/WEB-INF
 pki_tomcat_work_path=%(pki_instance_path)s/work
 pki_tomcat_work_catalina_path=%(pki_tomcat_work_path)s/Catalina
 pki_tomcat_work_catalina_host_path=%(pki_tomcat_work_catalina_path)s/localhost
diff --git a/base/server/python/pki/server/deployment/scriptlets/instance_layout.py b/base/server/python/pki/server/deployment/scriptlets/instance_layout.py
index 6ca9a374d529d1ed4c5b5bab1dd40a012205dc64..86968e22ee9cde74b733d12a3d23eff9a4c509cc 100644
--- a/base/server/python/pki/server/deployment/scriptlets/instance_layout.py
+++ b/base/server/python/pki/server/deployment/scriptlets/instance_layout.py
@@ -39,18 +39,22 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
             config.pki_log.info(log.SKIP_INSTANCE_SPAWN_1, __name__,
                                 extra=config.PKI_INDENTATION_LEVEL_1)
             return self.rv
+
         config.pki_log.info(log.INSTANCE_SPAWN_1, __name__,
                             extra=config.PKI_INDENTATION_LEVEL_1)
-        # establish instance logs
-        deployer.directory.create(deployer.master_dict['pki_instance_log_path'])
-        # establish instance configuration
-        deployer.directory.create(deployer.master_dict['pki_instance_configuration_path'])
-        # establish Apache/Tomcat specific instance
-        if deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+
+        # if this is the first subsystem
+        if deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
+            len(deployer.instance.tomcat_instance_subsystems()) == 1:
+
+            # establish instance logs
+            deployer.directory.create(deployer.master_dict['pki_instance_log_path'])
+
             # establish Tomcat instance configuration
-            deployer.directory.copy(deployer.master_dict['pki_source_server_path'],
-                                deployer.master_dict['pki_instance_configuration_path'],
-                                overwrite_flag=True)
+            deployer.directory.copy(
+                deployer.master_dict['pki_source_server_path'],
+                deployer.master_dict['pki_instance_configuration_path'])
+
             # establish Tomcat instance base
             deployer.directory.create(deployer.master_dict['pki_tomcat_common_path'])
             deployer.directory.create(deployer.master_dict['pki_tomcat_common_lib_path'])
@@ -67,7 +71,27 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
             deployer.symlink.create(deployer.master_dict['pki_instance_conf_log4j_properties'],
                                 deployer.master_dict['pki_instance_lib_log4j_properties'])
             deployer.directory.create(deployer.master_dict['pki_tomcat_tmpdir_path'])
-            deployer.directory.create(deployer.master_dict['pki_tomcat_webapps_path'])
+
+            # Copy /usr/share/pki/server/webapps to <instance>/webapps
+            deployer.directory.copy(
+                os.path.join(
+                    config.PKI_DEPLOYMENT_SOURCE_ROOT,
+                    "server",
+                    "webapps"),
+                deployer.master_dict['pki_tomcat_webapps_path'])
+
+            # If desired and available,
+            # copy selected server theme
+            # to <instance>/webapps/pki
+            if config.str2bool(deployer.master_dict['pki_theme_enable']) and\
+                os.path.exists(deployer.master_dict['pki_theme_server_dir']):
+                deployer.directory.copy(
+                    deployer.master_dict['pki_theme_server_dir'],
+                    os.path.join(
+                        deployer.master_dict['pki_tomcat_webapps_path'],
+                        "pki"),
+                    overwrite_flag=True)
+
             deployer.directory.create(deployer.master_dict['pki_tomcat_work_path'])
             deployer.directory.create(deployer.master_dict['pki_tomcat_work_catalina_path'])
             deployer.directory.create(deployer.master_dict['pki_tomcat_work_catalina_host_path'])
@@ -120,9 +144,6 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 deployer.master_dict['pki_resteasy_jettison_provider_jar_link'])
             deployer.symlink.create(deployer.master_dict['pki_scannotation_jar'],
                 deployer.master_dict['pki_scannotation_jar_link'])
-            if deployer.master_dict['pki_subsystem'] == 'TKS':
-                deployer.symlink.create(deployer.master_dict['pki_symkey_jar'],
-                    deployer.master_dict['pki_symkey_jar_link'])
             deployer.symlink.create(deployer.master_dict['pki_tomcatjss_jar'],
                 deployer.master_dict['pki_tomcatjss_jar_link'])
             deployer.symlink.create(deployer.master_dict['pki_velocity_jar'],
@@ -133,23 +154,31 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 deployer.master_dict['pki_xml_commons_apis_jar_link'])
             deployer.symlink.create(deployer.master_dict['pki_xml_commons_resolver_jar'],
                 deployer.master_dict['pki_xml_commons_resolver_jar_link'])
-        # establish shared NSS security databases for this instance
-        deployer.directory.create(deployer.master_dict['pki_database_path'])
-        # establish instance convenience symbolic links
-        deployer.symlink.create(deployer.master_dict['pki_database_path'],
+
+            # establish shared NSS security databases for this instance
+            deployer.directory.create(deployer.master_dict['pki_database_path'])
+            # establish instance convenience symbolic links
+            deployer.symlink.create(deployer.master_dict['pki_database_path'],
                             deployer.master_dict['pki_instance_database_link'])
-        deployer.symlink.create(deployer.master_dict['pki_instance_configuration_path'],
+            deployer.symlink.create(deployer.master_dict['pki_instance_configuration_path'],
                             deployer.master_dict['pki_instance_conf_link'])
-        deployer.symlink.create(deployer.master_dict['pki_instance_log_path'],
+            deployer.symlink.create(deployer.master_dict['pki_instance_log_path'],
                             deployer.master_dict['pki_instance_logs_link'])
+
+        if deployer.master_dict['pki_subsystem'] == 'TKS':
+            deployer.symlink.create(deployer.master_dict['pki_symkey_jar'],
+                deployer.master_dict['pki_symkey_jar_link'])
+
         return self.rv
 
     def destroy(self, deployer):
 
         config.pki_log.info(log.INSTANCE_DESTROY_1, __name__,
                             extra=config.PKI_INDENTATION_LEVEL_1)
+
         if deployer.master_dict['pki_subsystem'] == 'TKS':
             deployer.symlink.delete(deployer.master_dict['pki_symkey_jar_link'])
+
         if deployer.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
            deployer.instance.apache_instance_subsystems() == 0:
             # remove Apache instance base
@@ -165,6 +194,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
             if deployer.instance.apache_instances() == 0:
                 deployer.directory.delete(
                     deployer.master_dict['pki_instance_type_registry_path'])
+
         elif deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
              len(deployer.instance.tomcat_instance_subsystems()) == 0:
             # remove Tomcat instance base
@@ -183,4 +213,5 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
             if deployer.instance.tomcat_instances() == 0:
                 deployer.directory.delete(
                     deployer.master_dict['pki_instance_type_registry_path'])
+
         return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py b/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py
index ccbf4ea906c0de2ed951f66f22c51b5b183355ac..70f2ccc88a4036752fa8dd9903866d6ce389607e 100644
--- a/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py
+++ b/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py
@@ -40,76 +40,10 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                                      __name__,
                                     extra=config.PKI_INDENTATION_LEVEL_1)
                 return self.rv
+
             config.pki_log.info(log.WEBAPP_DEPLOYMENT_SPAWN_1, __name__,
                                 extra=config.PKI_INDENTATION_LEVEL_1)
 
-            # Copy /usr/share/pki/server/webapps/ROOT
-            # to <instance>/webapps/ROOT
-            deployer.directory.create(deployer.master_dict['pki_tomcat_webapps_root_path'])
-            deployer.directory.copy(
-                os.path.join(
-                    config.PKI_DEPLOYMENT_SOURCE_ROOT,
-                    "server",
-                    "webapps",
-                    "ROOT"),
-                deployer.master_dict['pki_tomcat_webapps_root_path'],
-                overwrite_flag=True)
-
-            deployer.directory.create(deployer.master_dict['pki_tomcat_webapps_common_path'])
-
-            # If desired and available,
-            # copy selected server theme
-            # to <instance>/webapps/pki
-            if config.str2bool(deployer.master_dict['pki_theme_enable']) and\
-               os.path.exists(deployer.master_dict['pki_theme_server_dir']):
-                deployer.directory.copy(deployer.master_dict['pki_theme_server_dir'],
-                                    deployer.master_dict['pki_tomcat_webapps_common_path'],
-                                    overwrite_flag=True)
-
-            # Copy /usr/share/pki/server/webapps/pki/js
-            # to <instance>/webapps/pki/js
-            deployer.directory.copy(
-                os.path.join(
-                    config.PKI_DEPLOYMENT_SOURCE_ROOT,
-                    "server",
-                    "webapps",
-                    "pki",
-                    "js"),
-                os.path.join(
-                    deployer.master_dict['pki_tomcat_webapps_common_path'],
-                    "js"),
-                overwrite_flag=True)
-
-            # Copy /usr/share/pki/server/webapps/pki/META-INF
-            # to <instance>/webapps/pki/META-INF
-            deployer.directory.copy(
-                os.path.join(
-                    config.PKI_DEPLOYMENT_SOURCE_ROOT,
-                    "server",
-                    "webapps",
-                    "pki",
-                    "META-INF"),
-                os.path.join(
-                    deployer.master_dict['pki_tomcat_webapps_common_path'],
-                    "META-INF"),
-                overwrite_flag=True)
-
-            # Copy /usr/share/pki/server/webapps/pki/admin
-            # to <instance>/webapps/<subsystem>/admin
-            # TODO: common templates should be deployed in common webapp
-            deployer.directory.create(deployer.master_dict['pki_tomcat_webapps_subsystem_path'])
-            deployer.directory.copy(
-                os.path.join(
-                    config.PKI_DEPLOYMENT_SOURCE_ROOT,
-                    "server",
-                    "webapps",
-                    "pki",
-                    "admin"),
-                os.path.join(
-                    deployer.master_dict['pki_tomcat_webapps_subsystem_path'],
-                    "admin"),
-                overwrite_flag=True)
-
             # Copy /usr/share/pki/<subsystem>/webapps/<subsystem>
             # to <instance>/webapps/<subsystem>
             deployer.directory.copy(
@@ -155,11 +89,39 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                                     deployer.master_dict['pki_tps_jar_link'])
             # set ownerships, permissions, and acls
             deployer.directory.set_mode(deployer.master_dict['pki_tomcat_webapps_subsystem_path'])
+
+            # Copy /usr/share/pki/<subsystem>/conf/Catalina/localhost/<subsystem>.xml
+            # to <instance>/conf/Catalina/localhost/<subsystem>.xml
+            deployer.file.copy(
+                os.path.join(
+                    config.PKI_DEPLOYMENT_SOURCE_ROOT,
+                    deployer.master_dict['pki_subsystem'].lower(),
+                    "conf",
+                    "Catalina",
+                    "localhost",
+                    deployer.master_dict['pki_subsystem'].lower() + ".xml"),
+                os.path.join(
+                    deployer.master_dict['pki_instance_configuration_path'],
+                    "Catalina",
+                    "localhost",
+                    deployer.master_dict['pki_subsystem'].lower() + ".xml"))
+
         return self.rv
 
     def destroy(self, deployer):
         if deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
             config.pki_log.info(log.WEBAPP_DEPLOYMENT_DESTROY_1, __name__,
                                 extra=config.PKI_INDENTATION_LEVEL_1)
+
+            # Delete <instance>/conf/Catalina/localhost/<subsystem>.xml
+            deployer.file.delete(
+                os.path.join(
+                    deployer.master_dict['pki_instance_configuration_path'],
+                    "Catalina",
+                    "localhost",
+                    deployer.master_dict['pki_subsystem'].lower() + ".xml"))
+
+            # Delete <instance>/webapps/<subsystem>
             deployer.directory.delete(deployer.master_dict['pki_tomcat_webapps_subsystem_path'])
+
         return self.rv
diff --git a/base/server/share/webapps/ROOT/META-INF/context.xml b/base/server/share/conf/Catalina/localhost/ROOT.xml
similarity index 100%
rename from base/server/share/webapps/ROOT/META-INF/context.xml
rename to base/server/share/conf/Catalina/localhost/ROOT.xml
diff --git a/base/server/share/webapps/pki/META-INF/context.xml b/base/server/share/conf/Catalina/localhost/pki.xml
similarity index 100%
rename from base/server/share/webapps/pki/META-INF/context.xml
rename to base/server/share/conf/Catalina/localhost/pki.xml
diff --git a/base/server/upgrade/10.0.99/04-FixLogFileOwnership b/base/server/upgrade/10.0.99/04-FixLogFileOwnership
index d7de7f96ff5e90fc73c84c3b043790b4baff006b..b63055f29d3da928bb0095c3eeaf76dd755c3ee3 100755
--- a/base/server/upgrade/10.0.99/04-FixLogFileOwnership
+++ b/base/server/upgrade/10.0.99/04-FixLogFileOwnership
@@ -51,14 +51,4 @@ class FixLogFileOwnership(pki.server.upgrade.PKIServerUpgradeScriptlet):
 
         log_dir = os.path.join('/var/log/pki', instance.name)
 
-        self._chown(log_dir, uid, gid)
-
-
-    def _chown(self, path, uid, gid):
-        os.chown(path, uid, gid)
-        for item in os.listdir(path):
-            itempath = os.path.join(path, item)
-            if os.path.isfile(itempath):
-                os.chown(itempath, uid, gid)
-            elif os.path.isdir(itempath):
-                self._chown(itempath, uid, gid)
+        pki.util.chown(log_dir, uid, gid)
diff --git a/base/server/upgrade/10.1.0/.gitignore b/base/server/upgrade/10.1.0/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..5e7d2734cfc60289debf74293817c0a8f572ff32
--- /dev/null
+++ b/base/server/upgrade/10.1.0/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/base/server/upgrade/10.1.99/01-MoveWebApplicationContextFile b/base/server/upgrade/10.1.99/01-MoveWebApplicationContextFile
new file mode 100755
index 0000000000000000000000000000000000000000..f3bbf4477abe01f9473f50d5deab79a2fffde47a
--- /dev/null
+++ b/base/server/upgrade/10.1.99/01-MoveWebApplicationContextFile
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+# Authors:
+#     Endi S. Dewata <edewata@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2013 Red Hat, Inc.
+# All rights reserved.
+#
+
+import grp
+import os
+import pwd
+import re
+
+import pki.server.upgrade
+
+
+class MoveWebApplicationContextFile(pki.server.upgrade.PKIServerUpgradeScriptlet):
+
+    def __init__(self):
+
+        self.message = 'Move web application context file'
+
+    def upgrade_instance(self, instance):
+
+        self.upgrade_webapp(instance, 'ROOT')
+        self.upgrade_webapp(instance, 'pki')
+
+    def upgrade_subsystem(self, instance, subsystem):
+
+        self.upgrade_webapp(instance, subsystem.name)
+
+    def upgrade_webapp(self, instance, webapp):
+
+        metainf_dir = os.path.join(instance.base_dir, 'webapps', webapp, 'META-INF')
+        self.backup(metainf_dir)
+
+        old_context_file = os.path.join(metainf_dir, 'context.xml')
+        self.backup(old_context_file)
+
+        catalina_dir = os.path.join(instance.base_dir, 'conf', 'Catalina')
+        self.backup(catalina_dir)
+
+        localhost_dir = os.path.join(catalina_dir, 'localhost')
+        self.backup(localhost_dir)
+
+        new_context_file = os.path.join(localhost_dir, webapp + '.xml')
+        self.backup(new_context_file)
+
+        # prepare target folder
+        if not os.path.exists(localhost_dir):
+            os.makedirs(localhost_dir)
+
+        # copy context file, don't overwrite existing file
+        pki.util.copyfile(old_context_file, new_context_file, overwrite=False)
+
+        # find uid and gid
+        registry_file = os.path.join(
+            pki.server.REGISTRY_DIR, 'tomcat', instance.name, instance.name)
+
+        with open(registry_file, 'r') as registry:
+            lines = registry.readlines()
+
+        for line in lines:
+            m = re.search('^PKI_USER=(.*)$', line)
+            if m:
+                user = m.group(1)
+            m = re.search('^PKI_GROUP=(.*)$', line)
+            if m:
+                group = m.group(1)
+
+        uid = pwd.getpwnam(user).pw_uid
+        gid = grp.getgrnam(group).gr_gid
+
+        # set file and folder ownership
+        pki.util.chown(catalina_dir, uid, gid)
+
+        # remove old context file
+        if os.path.exists(old_context_file):
+            os.remove(old_context_file)
+
+        # remove empty META-INF
+        if not os.listdir(metainf_dir):
+            os.rmdir(metainf_dir)
diff --git a/base/tks/shared/webapps/tks/META-INF/context.xml b/base/tks/shared/conf/Catalina/localhost/tks.xml
similarity index 100%
rename from base/tks/shared/webapps/tks/META-INF/context.xml
rename to base/tks/shared/conf/Catalina/localhost/tks.xml
diff --git a/base/tks/shared/conf/context.xml b/base/tks/shared/conf/context.xml
deleted file mode 100644
index 8b6fe490589481ed09a2e08cbd46004a0a1156df..0000000000000000000000000000000000000000
--- a/base/tks/shared/conf/context.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<!-- BEGIN COPYRIGHT BLOCK
-     Copyright (C) 2006-2010 Red Hat, Inc.
-     All rights reserved.
-     Modifications: configuration parameters
-     END COPYRIGHT BLOCK -->
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<!-- The contents of this file will be loaded for each web application -->
-<Context crossContext="true" allowLinking="true">
-
-    <!-- Default set of monitored resources -->
-    <WatchedResource>WEB-INF/web.xml</WatchedResource>
-	
-    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
-    <!--
-    <Manager pathname="" />
-    -->
-
-    <!-- Uncomment this to enable Comet connection tacking (provides events
-         on session expiration as well as webapp lifecycle) -->
-    <!--
-    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-    -->
-
-</Context>
diff --git a/base/tps-tomcat/shared/webapps/tps/META-INF/context.xml b/base/tps-tomcat/shared/conf/Catalina/localhost/tps.xml
similarity index 100%
rename from base/tps-tomcat/shared/webapps/tps/META-INF/context.xml
rename to base/tps-tomcat/shared/conf/Catalina/localhost/tps.xml
diff --git a/base/tps-tomcat/shared/conf/context.xml b/base/tps-tomcat/shared/conf/context.xml
deleted file mode 100644
index ba139add25c35874bcc12a6252e3ac0a62290d5a..0000000000000000000000000000000000000000
--- a/base/tps-tomcat/shared/conf/context.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<!-- BEGIN COPYRIGHT BLOCK
-     Copyright (C) 2006-2010 Red Hat, Inc.
-     All rights reserved.
-     Modifications: configuration parameters
-     END COPYRIGHT BLOCK -->
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<!-- The contents of this file will be loaded for each web application -->
-<Context crossContext="true" allowLinking="true">
-
-    <!-- Default set of monitored resources -->
-    <WatchedResource>WEB-INF/web.xml</WatchedResource>
-
-    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
-    <!--
-    <Manager pathname="" />
-    -->
-
-    <!-- Uncomment this to enable Comet connection tacking (provides events
-         on session expiration as well as webapp lifecycle) -->
-    <!--
-    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-    -->
-
-</Context>
-- 
1.9.3

