tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <craig...@apache.org>
Subject Re: Tomcat 4.1-dev web application management current design & proposal for improvements
Date Sun, 03 Mar 2002 01:44:24 GMT
See intermixed.

On Sat, 2 Mar 2002, Glenn Nielsen wrote:

> Date: Sat, 02 Mar 2002 10:06:59 -0600
> From: Glenn Nielsen <glenn@voyager.apg.more.net>
> Reply-To: Tomcat Developers List <tomcat-dev@jakarta.apache.org>
> To: tomcat-dev@jakarta.apache.org
> Subject: Tomcat 4.1-dev web application management current design &
>     proposal for  improvements
>
>   Tomcat 4.1-dev HEAD web app management current design and proposal for
> improvements
>
> Current Behaviour
> =================
>
> Here is a stab at documenting how the Tomcat 4.1 dev HEAD CVS branch
> manages web applications based on reviewing user documentation, code,
> and testing.  Please review and add corrections if needed.
>
> Tomcat Startup
> --------------
>
> Context's configured in server.xml deployed.
>

For people who haven't found it yet, this functionality is in
org.apache.catalina.startup.HostConfig.

> if( autoDeploy == true )
>
>   Deploys Context configurations found in appBase/*.xml.
>     calls host.install() with a file URL to Context xml config file.
>     The Context *.xml file can specify any directory on the server
>     as the docBase and it will be instantiated as a Context, as long
>     as the SecurityManager doesn't prevent access.
>
>   Deploys *.war files found in appBase/*.xml
>     if( unpackWARs == true )
>        calls host.install() with a file: URL after expanding the war file.
>     if( unpackWARs == false )
>         calls host.install() with a jar:file: URL to war.
>
>   Deploys directories found in appBase.
>     calls host.install() with a file URL to directory.
>
> Tomcat runtime AutoDeploy
> -------------------------
>
> A background thread is started.
>
> if( autoDeploy == true )
>    the actions above for autoDeploy are taken each 15 seconds.
>
> Contexts are checked for a modified web.xml, if detected the
> Context is stopped then started again.
>
> Tomcat Manager
> --------------
>
> - deploy ** Not available via HTMLManagerServlet
>

I don't personally believe in HTMLManagerServlet.  Manager was designed to
be scriptable by tools, and an HTML UI for managing Tomcat needs to do a
lot more than just this, like the admin tool will do.

> Installs a web application using a war file sent via an HTTP PUT.
> The deployed application does not persist if Tomcat is restarted.
>

Ultimately, persistence should be handled by mechanisms to update
server.xml -- but this is really an all-or-nothing thing.

Currently, deploy doesn't support sending a context configuration XML file
along with the WAR -- it will need this for webapps that have JNDI
resource references that need to be configured (either as absolute values
or as links to global JNDI resources>, or custom logger/manager
configurations, or ....

> - install
>
> Installs a web application using a remote Context config xml
> file and a war file or directory located on the server.
> You can specifiy any file URL as long as the SecurityManager
> doesn't prevent access. Such as "file:/". And the Context config
> xml file can specify any docBase.  The installed application does
> not persist if Tomcat is restarted unless the directory or war
> file existed in the Host's appBase.
>

You can install a config file, a WAR (or unpacked directory), or both.  In
the latter case, the "docBase" provided in the config file is ignored.  (I
would expect we'd implement this the same way when deploy knows how to do
a multipart upload.

Note that install works only if Tomcat is on the same machine, whereas
deploy can be executed remotely.  On the other hand, it's faster because
the WAR does not need to be copied.

Persistence issues here are similar to that for deploy.

> - start
>
> Starts the Context if it exists and is currently stopped.
>
> - reload
>
> Reloads Context if it is a directory, does not reload if
> it is running from a war file. A reload does not reload
> the web applications web.xml. So if you make configuration
> changes to the web.xml file you need to do a stop/start.
>

I'm not sure that stop/start actually does the right thing currently
(haven't ever looked at that scenario), because it doesn't remove anything
that was configured by the "old" web.xml file.

> - stop
>
> Stops the Context if it exists
>
> - remove
>
> Removes the Context from a running instance of Tomcat and
> stops it.  Does not remove any files.
>
> - undeploy ** Not available via HTMLManagerServlet
>
> Removes Context from host, delete's app directory or war file.
> Does not delete work dir.
>

Deleting the work dir is something to think about.  It takes time, but
guarantees the app a clean slate if it is redeployed.

> - list
>
> Lists information on existing contexts.
>
> - sessions
>
> Lists information on the number of sessions for Context
>
> Tomcat Shutdown
> ---------------
>
> Each Context is removed using Host.remove(contextpath).
> This removes the Context object from the Host container
> and performs a Context stop().
>

Therefore, anything we change in the remove command (such as possibly
removing the work dir here as well) would also be done at Tomcat shutdown
unless we special case it.  In particular, this would interfere with one
Tomcat feature that is popular among some groups of developers - saving
the current sessions and reloading them at the next startup (which also
works across the reload command above).

>
> *********************************************************************
>
>
> [PROPOSAL]
>
> Here is a proposal for improving how Tomcat manages web applications.
> My goals in creating this were to address security concerns and to
> improve the ability for virtual hosted customers to manager their
> own applications. Please review.
>
> core/StandardHost.java
> ======================
>
> Suggestions for improvement
> ---------------------------
>
> The install and deploy manager tasks along with the autoDeploy
> of a Context *.xml in a Host's appBase make it possible for
> someone who has access to the manager or write file access to
> the appBase directory on the server to specify a docBase any
> where on the server Tomcat is running on.  When virtual hosting
> customers sites this is a big security problem.
>
> Restrict instantiation of Contexts to a directory or war
> file located in the Host's appBase. If this is too restrictive
> for some, then add a Host attribute of globalDeploy=(true|false)
> with a default of false.  If globalDeploy is true an application
> can be deployed using a file or war from outside of the Host's
> appBase.
>

For deploy, we've got total control over where the WAR is placed.
If/when the ability to deploy a config file as well is supported (Glenn,
how do you currently deal with vhost customers that need JNDI resources?),
we can do the same thing about ignoring the docBase in the config file,
and controlling where the config file and the corresponding WAR or
directory is placed.

For install, restricting the directory to be under appBase would interfere
with the ability to do webapp development local to my user home directory
(by installing the app, doing edits in place, reloading as necesary).  It
would also remove a capability that many production applications rely on,
to *not* require all webapps to be installed in a common subdirectory.
You also could not implement the "user home directories" feature like
Apache does (http://localhost:8080/~craigmcc), which is currently
supported.

One alternative might be to parameterize Manager to turn off support for
install completely.  After all, you can accomplish what you want by
setting autoDeploy to true and then just dropping the WAR or directory
into the "appBase" directory for that host.


> startup/HostConfig.java
> =======================
>
> Here are some inconsistencies in the HostConfig
> -----------------------------------------------
>
> A background thread is always started.  From the comments
> for the thread methods it isn't clear what it does.
>
> In some places the comments talk about session timeouts,
> in other places checking for modified classes, and in other places
> it mentions checking for shutdown, and the checkInterval variable
> says check periodically for web app deployment.
>
> Looking at the code, this is what it does.
>
> Every 15 seconds it wakes up.
>
>   if autoDeploy=true, it checks for new web apps to deploy.
>
>   Then it checks each context to see if the web.xml has changed.
>   If it has changed it does a stop, then start of the Context.
>
> Suggested improvements
> ----------------------
>
> Cleanup the misleading comments.
>
> There is only one flag used for determining if you want
> autoDeploy which applies both at startup and runtime interval
> deployment.
>
> These two should be separate.  It is very likely that you would
> want autoDeploy at Tomcat startup, but not checks at 15 second
> intervals. Remove the autoDeploy attribute and add the following:
>
> startupAutoDeploy=(true|false) default = true
> intervalAutoDeploy=(true|false) default = false
>

Agree with two flags.  However, I'd rather leave one of them named
"autoDeploy" so we don't break all current server.xml files.  Maybe:
    startupAutoDeploy --> autoDeploy
    intervalAutoDeploy --> liveDeploy
or something like that?  Defaults would be true for both to mimic current
behavior.

> The checks for a modified web.xml which stop then start a Context
> should only be done if intervalAutoDeploy=true. I haven't found any
> user documentation about Context start/stop if the web.xml is modified,
> document this feature.
>

Per above, I don't think it works correctly, either.

> Only start the background thread if intervalAutoDeploy=true.
>

Yep.

> Deploying applications using a Context *.xml file located in the
> Host's appBase or via the manager servlet is a security problem.
> Instantiation of a new Context runs with the SecurityManager permissions
> granted to catalina.  This allows anyone with write access to the
> appBase directory for a Host or access to the manager servlet to configure
> directories and war files anywhere catalina has file read permission.
> This affects the docBase, workDir, and loggers.
>
> Add an attribute to disable it:
>
> deployXML=(true|false) default=false
>

I'm ok with an option, but suggest the default is true.  When you are not
in a "hosting customers" environment, it is very valuable to be able to
configure anything you can put in a <Context> element, without having to
mess with server.xml and restarting Tomcat to d it.

>
> servlets/ManagerServlet.java
> ============================
>
> Questions
> ---------
>
> The install task used to support any URL, now it only
> supports URL's for local files on the server.  But
> HTTP PUT was implemented for the deploy task. Was this
> changed to get around the JVM bug related remote access
> to and reading of a JAR (zip)? I checked the CVS log
> for the ManagerServlet and it wasn't mentioned.
>

I could never get jar:http:..... URLs to work right, so it didn't seem
reasonable to allow the user to try and get frustrated.  In addition, the
advent of the deploy command provided a better way to deal with remote
JARs (and the performance of the installed webapp will be better as well,
because the WAR is uploaded).

> Suggested improvements
> ----------------------
>
> - deploy
>
> Currently war files deployed do not persist past a Tomcat restart.
> That makes this pretty useless for someone to use for managing their
> applications on a production system.
>

This is true for install as well, unless you happen to have installed an
app in the appBase directory and autoDeploy is true.  It's also a bigger
issue than just new apps being deployed, since the admin app will let you
adjust basically every property on every component of a running Tomcat
server, and you want to be able to save all of that as well.

I've got some ideas for how to deal with this globally that are not ready
for prime time yet, but I'd prefer *not* to try to deal with just part of
the problem.

> If the Host unpackWARs==true
>   Install the war file in the Host's appBase as {context-path}.war.
>   (The war is required to exist in order to perform the new update task)
>   Expand the war file into a directory named {context-path} in the
>   Host's appBase.  If the directory or war file already exist in the
>   Host's appBase, the deploy should fail.
>

I'm ok with respecting unpackWARs on a deploy (but not on an install --
because install already gives you the choice of installing a directory or
a WAR, but deploy doesn't).

Where to put the WAR or directory is an issue that is affected by the
persistence of the entire Tomcat configuration, so it should be dealt with
holistically.

> If the Host unpackWARs==false
>   Install the war file in the Host's appBase as {context-path}.war.
>   If the war exists in the Host's appBase, the deploy should fail.
>
> - install
>
> Change the name to "add", install implies you are putting
> something on the server.  And "add" is the counterpart to remove.
> So "add" would add a Context configuration, "remove" removes a Context
> configuration.
>

I do not like gratuitously breaking backwards compatibility.

> Make it easier to specify a war or directory within the Host's
> appBase.  If the URL is not a file URL create a file URL relative to
> the Host's appBase.
>

I don't get why you need to use *any* manager command if this is what you
want?  Just drop in the WAR or directory, turn on intervalAutoDeploy (or
whatever it is called), and the app is "installed".

> - start
>

StandardContext.start(), among other things, processes the web.xml file.
But, I don't think we're currently cleaning out the
servlets/filters/listeners/etc. set up previously, so that needs to be
added in order to make "stop/start" do the expected thing.

> - reload

If we make stop/start work correctly, it might be worth re-implementing
reload in terms of that instead of the special case it currently is.  On
the down side, this would make reloads slower if all you did was recompile
a bean class.

>
> - update
>
> Add a new task called update.  Requires a context path for an
> existing Context and performs an HTTP PUT of a new war file.
>
> Some applications need to exist in a context directory because they
> need to manage data files stored within the context directory.  An
> update allows for the web application resources to be updated without
> removing any existing data generated by an application.
>

IMHO, this is a poor architecture choice for deployed production
applications ... but lots of people do it.

> if the Host unpackWARs==false
>   Stop the Context, remove the War file, remove the Context workDir.
>   Install the new war in the Host's appBase and start the context.
>   Kind of a one step undeploy/deploy.
>
> if the Host unpackWARs==true
>   If the context doesn't exist, fail.  If the context directory or
>   the war file doesn't exist, fail.
>
>   Stop the Context. Remove any files in the Context directory which
>   exist in the old war file.  Remove the old war file. Remove the
>   Context workDir.
>
>   Install the war file in the Host's appBase as {context-path}.war.
>   (The war is required to exist in order to perform the new update task)
>   Expand the war file into a directory named {context-path} in the
>   Host's appBase.
>

You might be better off with a "patch" command that accepts a JAR (instead
of a WAR -- so you can only replace what you want to and don't need a
complete webapp) that does:  stop, replace/add files from the JAR, start.

Removing the work dir means you give up saving sessions across this
operation, which is not always what you want -- it should be optional (or
we need to change where SESSIONS.ser is kept so that it's not affected).

> - stop
>
> - remove
>
> - undeploy
>
> Delete workDir in addition to deleting Context directory or
> war file when undeploying a Context. Per the Servlet spec
> the workDir isn't required to be maintained across container
> restarts, so there should be no problem removing it when an
> application is undeployed.
>

As mentioned above, this would currently disable the "save sessions across
restart" feature, but that can be dealt with in a different way.

> - list
>
> - sessions
>
> Add the ability to track session creation by the request URI
> which created the session.  I haven't looked into how hard this
> would be to implement.  A web application which handles alot of
> unique visitors can end up creating 1000's of sessions.  This eats
> up JVM memory and affects performance. The default behaviour of a
> JSP page is to create a session. Listing what request URI
> created a Session and how many will make it much easier to find
> and fix those JSP pages, etc. which are creating unnecessary sessions.
>

The simplest technique for this would be to write a Filter that overrides
the getSession() method and keeps track of when a new session is actually
created (session.isNew()).  Such a filter could be non-invasively added to
any webapp (on any 2.3 based container) without having to be a Tomcat
feature.

Inside Tomcat, the current APIs don't really lend themselves to tracking
this -- the Manager.createSession() method doesn't accept any argument to
specify the related request (indeed, Tomcat doesn't care if you create a
session *outside* the context of a particular request), so you'd have to
go track down the places that this is called and instrument them.  But, if
you wanted, you could create a Valve that did the same thing inside Tomcat
that the Filter suggested above does at the application level.


> servlets/HTMLManagerServlet.java
> ================================
>
> Suggested improvements
> ----------------------
>
> Add the deploy task.
>
> Add the undeploy task. This should include a confirmation page
> before actually undeploying the context path.
>
> Add the update task.  This should include a confirmation page
> before actually performing the web application update.
>
> Increase the font size for the context information, using Netscape 4.7
> I can barely read it.
>

Or just get rid of the thing ...

> ant/UpdateTask.java
> ===================
>
> Create a new ant task for performing updates.
>


or patch ...


> *********************************************************************
>
> Regards,
>
> Glenn
>
> ----------------------------------------------------------------------
> Glenn Nielsen             glenn@more.net | /* Spelin donut madder    |
> MOREnet System Programming               |  * if iz ina coment.      |
> Missouri Research and Education Network  |  */                       |
> ----------------------------------------------------------------------
>
> --
> To unsubscribe, e-mail:   <mailto:tomcat-dev-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: <mailto:tomcat-dev-help@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <mailto:tomcat-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:tomcat-dev-help@jakarta.apache.org>


Mime
View raw message