Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Using Groovy for Bash (shell) Operations

DZone's Guide to

Using Groovy for Bash (shell) Operations

· Java Zone ·
Free Resource

The CMS developers love. Open Source, API-first and Enterprise-grade. Try BloomReach CMS for free.

Recently I needed to create a groovy script that deletes some directories in a Linux machine.
Here’s why:
1.
We have a server for doing scheduled jobs.
Jobs such as ETL from one DB to another, File to DB etc.
The server activates clients, which are located in the machines we want to have action on them.
Most (almost all) of the jobs are written in groovy scripts.

2.
Part of our CI process is deploying a WAR into a dedicated server.
Then, we have a script that among other things uses soft-link to direct ‘webapps’ to the newly created directory.
This deployment happens once an hour, which fills up the dedicated server quickly.

So I needed to create a script that checks all directories in the correct location and deletes old ones.
I decided to keep the latest 4 directories.
It’s currently a magic number in the script. If I want / need I can make it as an input parameter. But I decided to start simple.

I decided to do it very simple:
1. List all directories with prefix webapp_ in a known location
2. Sort them by time, descending, and run delete on all starting index 4.

def numberOfDirectoriesToKeep = 4
def webappsDir = new File('/usr/local/tomcat/tomcat_aps')
def webDirectories = webappsDir.listFiles().grep(~/.*webapps_.*/)
def numberOfWeappsDirectories = webDirectories.size();
 
if (numberOfWeappsDirectories >= numberOfDirectoriesToKeep) {
  webDirectories.sort{it.lastModified() }.reverse()[numberOfDirectoriesToKeep..numberOfWeappsDirectories-1].each {
    logger.info("Deleteing ${it}");
    // here we'll delete the file. First try was doing a Java/groovy command of deleting directories
  }
} else {
  logger.info("Too few web directories")
}

It didn’t work.
Files were not deleted.
It happened that the agent runs as a different user than the one that runs tomcat.
The agent did not have permissions to remove the directories.

My solution was to run a shell command with sudo.

I found references at:
http://www.joergm.com/2010/09/executing-shell-commands-in-groovy/
and
http://groovy.codehaus.org/Executing+External+Processes+From+Groovy

To make a long story short, here’s the full script:

import org.slf4j.Logger
import com.my.ProcessingJobResult

def Logger logger = jobLogger
//ProcessingJobResult is proprietary 
def ProcessingJobResult result = jobResult

try {
	logger.info("Deleting old webapps from CI - START")
	def numberOfDirectoriesToKeep = 4 // Can be externalized to input parameter
	def webappsDir = new File('/usr/local/tomcat/tomcat_aps')
	def webDirectories = webappsDir.listFiles().grep(~/.*webapps_.*/)
	def numberOfWeappsDirectories = webDirectories.size();

	if (numberOfWeappsDirectories >= numberOfDirectoriesToKeep) {
		webDirectories.sort{it.lastModified() }.reverse()[numberOfDirectoriesToKeep..numberOfWeappsDirectories-1].each {
			logger.info("Deleteing ${it}");
			def deleteCommand = "sudo -u tomcat rm -rf " + it.toString();
			deleteCommand.execute();
		}
	} else {
		logger.info("Too few web directories")
	}
	result.status = Boolean.TRUE
	result.resultDescription = "Deleting old webapps from CI ended"
	logger.info("Deleting old webapps from CI - DONE")
} catch (Exception e) {
	logger.error(e.message, e)
	result.status = Boolean.FALSE
	result.resultError = e.message
}

return result

BTW,
There’s a minor bug of indexes, which I decided not to fix (now), as we always have more directories.



BloomReach CMS: the API-first CMS of the future. Open-source & enterprise-grade. - As a Java developer, you will feel at home using Maven builds and your favorite IDE (e.g. Eclipse or IntelliJ) and continuous integration server (e.g. Jenkins). Manage your Java objects using Spring Framework, write your templates in JSP or Freemarker. Try for free.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}