Using Groovy for Bash (shell) Operations
Recently I needed to create a groovy script that deletes some directories in a Linux machine. Here’s why:
- 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.
- 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:
- List all directories with prefix webapp_ in a known location
- 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:
and:
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.
Reference: | Using Groovy for Bash (shell) Operations from our JCG partner Eyal Golan at the Learning and Improving as a Craftsman Developer blog. |