add / modify files in windows (tomcat webapps)

nainil
nainil used Ask the Experts™
on
I am trying to locate a solution which will assist me in pushing new files.

There are several tomcat instances (5 or 6) running on one machine. My task is to upgrade the tomcat instances to have the latest application files under WebApps folder. One method is to go in and manually put the files (new and existing) under each folder. This is tiresome and can lead to several errors. Is there any-way to automate the same?

Is there a GUI which could serve as a "PUSH" mechanism where I can select a tomcat instance and say "Send new files"?

I guess one way is to use a DOS Batch script which will add / replace files... Is there sometype of working script which I can use which will log all actions (like adding a new file or replacing a file)?

Thank you.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Meir RivkinFull stack Software Engineer

Commented:
i'd have a config file which lists all the folders where the application files resides (that needs to be updated).
also it will have the location of the updated files which in turn will backup the current app files (before overwrite) to backup folder, and then update them.

then have a batch/powershell script which reads the config and update the application files accordingly.

in time, the backup folder can have sub folders with the update date time as the folder name so in the future you could track all the udpates you have done the application files and if something went wrong, you can pull the previous app file based on the date time.

Author

Commented:
Thanks for the suggestion sedgwick. Sure, backup of existing files is important.

Is Batch scripting an ideal solution? is there any GUI utility which can perform the same operation? Any options?
Meir RivkinFull stack Software Engineer

Commented:
i can make u a powershell script that can do the job in 10 minutes.
having gui app is nice but i think its not something that you would like to put effort and time into.
you can start with a simple script which do the job and in future if you see that u want to add more fucntionality into the whole thing u might consider having a gui app for that matter.

Author

Commented:
Thanks sedgwick. Can you please help to get me started with your script?

the powershell script, will it be compatible with Windows server 2003 / 2008 ?
Meir RivkinFull stack Software Engineer

Commented:
Ues it will.
u might need to allow poweshell execution first using set-executionpolicy but well get to that once ill post the script.
Basically the xml based config file will have the list of app files to update and the backup folder to copy the files to before the update.

Author

Commented:
Perfect. I will wait for your script...
Meir RivkinFull stack Software Engineer

Commented:
here's the structure of the config file:
<Configuation>
<BackupFolder>c:\temp\buckup</BackupFolder>
<Log>c:\temp\buckup\pslog.log</Log>
<AppFiles>
<File>
<Source>c:\temp\src\test1.config</Source>
<Dest>c:\temp\dest\test1.config</Dest>
</File>
<File>
<Source>c:\temp\src\test2.config</Source>
<Dest>c:\temp\dest\test2.config</Dest>
</File>
<File>
<Source>c:\temp\src\test3.config</Source>
<Dest>c:\temp\dest\test3.config</Dest>
</File>
<File>
<Source>c:\temp\src\test4.config</Source>
<Dest>c:\temp\dest\test4.config</Dest>
</File>
</AppFiles>
</Configuation>

Open in new window


and here's the script.
cls
$xml = [xml](gc "c:\temp\ps.config")
$backupFolder = $xml.Configuation.BackupFolder
$logfile = $xml.Configuation.Log
$log = (Get-Date -Format G) +"`r`n"

#loop the <File> tags
$xml.Configuation.AppFiles.File | foreach{
	$src = $_.Source
	$dest = $_.Dest
	if( Test-Path $src){
	
		#create the backup sub folder 
		$datetime =  Get-Date -format MM.dd.yyyy.HH.mm.ss
		$backupsubfolder = join-path $backupFolder $datetime
		
		#create backup sub folder if doesn't exists
		if((Test-Path $backupsubfolder) -eq $False){
			md $backupsubfolder 
		}
		
		#check if destination file exists
		if( Test-Path $dest){
			$name = (Get-Item $dest).name + ".bak"
			$newdest = join-path $backupsubfolder $name
			
			#move destination file to the backup folder 
			#and add extension .bak to the file name
			mi $dest $newdest
			
			#log action
			$log = $log + "Backup " +$dest+ " as "+ $newdest+"`r`n"
			
			#copy source file
			Copy-Item $src $dest
			
			#log action
			$log = $log +"Copy " +$src +" to "+ $dest+"`r`n"	
		}
		else{
			#destination file doesn't exists so only copy source file
			Copy-Item $src $dest
			$log = $log +"Copy " +$src +" to "+ $dest+"`r`n"
		}
	}else{
		#log source file not found
		$log =$log + $src + " Could not be found, skip file"+"`r`n"
	}
}

#append new log to log file
ac $logfile $log 

Open in new window


i've added comments almost on each line to make the script as readable as possible.
i suggest you to test the script on some temporary folder like i did just to make sure it covers different use cases.
basically, the script is great for any update/backup files.
the logic is this:

for each <file> tag, first check if source file exists, if not log and skip to next file.
then create the destination folder under the backup to which the source file will be moved.
this folder name is date time formatted: MM.dd.yyyy.HH.mm.ss
so for example if i'd have run the script right now, the subfolder would have called:
04.17.2012.22.48.37 --> which is Apr 17th 2012 10:48:37 (PM)

in addition i added .bak to the extension of the file extension so if the source file called web.config, it will be moved and renamed to web.config.bak

in case destination file doesn't exists, i simply copy the source file to destination target and rename it to match the <Dest> tag value.

for example:
<File>
<Source>c:\temp\1.config</Source>
<Dest>c:\windows\2.config</Dest>
</File>

if destination file exists, it will be renamed to 2.config.bak and moved to the backup folder then i copy 1.config from c:\temp to c:\windows and rename it to 2.config.

if destination file does not exists, i simply copy 1.config from c:\temp to c:\windows and rename it to 2.config.

for each copy/move action, i append the action to the logfile which is defined in the configuration file.

enjoy :)

Author

Commented:
sedgwick:
Thank you so much for the script. I tried it locally and it works as you described.

My application has several directories and sub-directories. (40 folders, 1000+ files). It probably does not work when the sub-directory does not exist.

Also, I am wondering what is a good way to generate the XML with the source and destination file listing... Any other way to feed the script with the source and destination listing?

Once again, thanks a tonne for what you have shared!
Meir RivkinFull stack Software Engineer

Commented:
Can u give me an example for a use case where it wont work?
I can modify the script to accept differet sources such as
Csv or xls or simple txt file.
I understand the hassle of creating the xml but if
 the app files locations can be added to the xml progrmically
then it would be great.
We need to build a pattern when looking for the app files.
Meir RivkinFull stack Software Engineer

Commented:
for instance if u tell me that all app files are located under
/usr/local/jakarta/tomcat/apps/
and their extension is.config

then i can find them and create the xml.
i can also map the source and destination files by their names or something like that.

Author

Commented:
Tweaking script:
Src has a folder named src2
Desc does not have the folder dest2

When I put the src2 file in config, i ran into an error that dest2 did not exist.

For Config File:
all our app related files have multiple extensions (like .properties, .class, .jks, .jars) etc and are saved under tomcat\webapps\MyApp

Under MyApp we have WEB-INF (under that classes --> under that we have the real application based folders), Lib etc. Lib (.jar) may need the tomcat application to be disabled before we move / backup them as they may be in use.


--------

On a side note:

can we just input the source tomcat folder and use that as a base. When the script runs, it prompts us for the destination tomcat folder. The script will iterate and step down into each and every folder under source and backup / replace the same at the destination folder.

Or, we could simply move the whole myapps folder from destination, and dump the src myapps folder into its place. Except for two or three files (if we could list them as an exception) all other files will be the same.
Meir RivkinFull stack Software Engineer

Commented:
agreed, its better to backup the whole folder rather than backup files here and there.
so lets say the config will have the myapps folder path to backup, and a destination folder which is the backup folder.

in regards to disable tomcat applications, i can do that from the script, so we can put the application names in the config and before the backup, the script will disable/stop them and resume after the backup is complete.

what do u think?

Author

Commented:
I am envisioning something like this:

Main Menu:

    install new tomcat
        Get tomcat instance name
        create a tomcat instance folder (4 locations)
        copy files
        edit server.xml
        edit properties (custom)
        set javahome
        set tomcathome
        install tomcat service
        run DB queries
        disable one tomcat

    upgrade application files
        identify the application to be upgraded
        backup existing files
        stop service
        replace new files
        run DB queries
        start service
    exit

Open in new window


I am not too worried about the "install new tomcat"... That is something which is just scripting commands.

do you believe that is do-able?
Meir RivkinFull stack Software Engineer

Commented:
anything is doable using powershell :)

lets start with creating the config structure.
it will help me if u post an example of full location of folder u wish to backup.
is the tomact instance name is inside the path?
cause then we can have a list of tomcat instances names:
<tomcat_instances>
<name>
</name>
<name>
</name>
</tomcat_instances>

and i can generate the path for each instance and backup the relevant folder.

Author

Commented:
The directory to backup is located at:
d:\Applications\tomcat6_XXXX\webapps\myapp1
d:\Applications\tomcat6_YYYY\webapps\myapp1

etc.

The tomcat instance name is in the path with a code or a name (XXXX, YYYY etc).

Does this help?
Meir RivkinFull stack Software Engineer

Commented:
yes it is great.

do the app files which need to be updated and located under the locations u posted are the same for every instance?

cause then we can have a list of instance names by which i can generate the location for each instance, and also the source location of the newly app files.

to sum up the structure is like this:

<config>
<backup_folder></backup_folder>  // backup folder location
<source_folder>
<location></location>                          //source folder location
<files>                                                       // app files list from source folder location (optional)
<file></file>
<files>
</source_folder>
<tomcat_instances>                            //list of instances names
<name></name>
</tomcat_instances>
</config>

<files> tag is optional, if exists i copy only the files in the list from the source folder , if missing, i copy all files from source folder.

is that covers everything?

Author

Commented:
do the app files which need to be updated and located under the locations u posted are the same for every instance?
>>> I am probably confused here, but, I will try to explain what I can:
The tomcats are all in one folder. The app structure remains common for all tomcats (source and destination).

to make this more interactive, I would ask the user for the tomcat instance which they want to upgrade, and that can be made a part of the tomcat_instances tag in the config file dynamically.

This will mean I can have just a config file with the source folder location and then, based on the user input, I can simply accept new tomcat instance name to be upgraded and perform the backup/ update operation.
Full stack Software Engineer
Commented:
config:
<Configuation>
<BackupFolder>c:\temp\backup</BackupFolder>
<Log>c:\temp\backup\pslog.log</Log>
<source>c:\tomcat\upgrade</source>
<dest>d:\Applications\tomcat6_{instance_name}\webapps\myapp1</dest>
</Configuation>

i replace the {instance_name} when user input valid instance name.
the script:

cls
$xml = [xml](gc "c:\temp\upgrade.config")
$backupFolder = $xml.Configuation.BackupFolder
$logfile = $xml.Configuation.Log
$source = $xml.Configuation.Source
$dest = $xml.Configuation.Dest
$shell = new-object -comobject wscript.shell
$path = ''
$instname = ''

if(!(Test-Path $backupFolder)){
	md $backupFolder
}

do{
	$instname = Read-Host 'Please enter instance name to upgrade? (Enter key to canecl)'
	if($instname -eq $null){
		exit;
	}
	
	$path = $dest -replace "{instance_name}", $instname
	if(Test-Path $path){
		break;
	}
		
	$shell.popup('invalid instance name '+ $instname)
}while(1)

$backuppath = Join-Path $backupFolder $instname
$backuppath = Join-Path $backuppath (get-date).tostring("MMddyyyyHHmmss")

md $backuppath 

$logtxt = (Get-Date -Format G) +"`r`n"
mi -path ($path + '\*') -Destination $backuppath
$logtxt += 'backup '+$path + ' to ' + $backuppath+"`r`n"
ac $logfile $logtxt

copy-Item -path ($source + '\*') -Destination $path
$logtxt = 'copy from '+$source + ' to ' + $path+"`r`n"
ac $logfile $logtxt

Open in new window

Author

Commented:
Thank you.. let me try it out. Appreciate your help. I will share my findings in some time and update!
Meir RivkinFull stack Software Engineer

Commented:
good luck

Author

Commented:
I am sorry I have not been able to work on this. Will send an update today!
Meir RivkinFull stack Software Engineer

Commented:
thats cool

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial