Skip to content

Commit 22bdd1f

Browse files
Sbachmei/mic 6290/move cleanup to jenkinsfile (#60)
1 parent b5b1b62 commit 22bdd1f

File tree

2 files changed

+196
-1
lines changed

2 files changed

+196
-1
lines changed

CHANGELOG.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
**2.0.5 - 8/8/2025**
2+
3+
- Create pipeline to clean up Jenkins build directories
4+
15
**2.0.4 - 8/6/2025**
26

37
- Revert v2.0.3
48

5-
**2.0.3 - 8/5/2025** (removed)
9+
**2.0.3 - 8/5/2025**
610

711
- Use Jenkins node /tmp/ dir (reversion from v2.0.2) until permissions get resolved
812

Jenkinsfile.cleanup

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
pipeline {
2+
agent none // Defined explicitly in each stage
3+
4+
environment {
5+
DIRS_TO_CLEAN_PER_NODE = '/tmp,/opt/jenkins/workspace'
6+
DIRS_TO_CLEAN_SHARED = '/mnt/team/simulation_science/priv/engineering/jenkins/envs'
7+
DAYS_OLD = '3'
8+
}
9+
10+
options {
11+
skipDefaultCheckout()
12+
timeout(time: 60, unit: 'MINUTES')
13+
timestamps()
14+
buildDiscarder(logRotator(numToKeepStr: '30'))
15+
}
16+
17+
stages {
18+
stage('Shared Directory Cleanup') {
19+
// Can use any node, really
20+
agent { node 'simsci-ci-coordinator-01' }
21+
steps {
22+
script {
23+
cleanDirs("shared")
24+
}
25+
}
26+
post {
27+
always {
28+
cleanWs()
29+
dir("${env.WORKSPACE}@tmp") {
30+
deleteDir()
31+
}
32+
}
33+
}
34+
}
35+
36+
stage('Coordinator Node Cleanup') {
37+
// NOTE: Confusingly, simsci-ci-coordinator-01 is actually simsci-jenkinsagent-ci-p02
38+
agent { node 'simsci-ci-coordinator-01' }
39+
steps {
40+
script {
41+
cleanDirs("per-node")
42+
}
43+
}
44+
post {
45+
always {
46+
cleanWs()
47+
dir("${env.WORKSPACE}@tmp") {
48+
deleteDir()
49+
}
50+
}
51+
}
52+
}
53+
54+
stage('Jenkins Agent Node Cleanup') {
55+
agent { node 'simsci-jenkinsagent-ci-p01' }
56+
steps {
57+
script {
58+
cleanDirs("per-node")
59+
}
60+
}
61+
post {
62+
always {
63+
cleanWs()
64+
dir("${env.WORKSPACE}@tmp") {
65+
deleteDir()
66+
}
67+
}
68+
}
69+
}
70+
71+
stage('Slurm Build Node Cleanup') {
72+
agent { node 'simsci-slurm-sbuild-p01' }
73+
steps {
74+
script {
75+
cleanDirs("per-node")
76+
}
77+
}
78+
post {
79+
always {
80+
cleanWs()
81+
dir("${env.WORKSPACE}@tmp") {
82+
deleteDir()
83+
}
84+
}
85+
}
86+
}
87+
88+
stage('Built-In Node Cleanup') {
89+
agent { node 'built-in' }
90+
steps {
91+
script {
92+
cleanDirs("per-node")
93+
}
94+
}
95+
post {
96+
always {
97+
cleanWs()
98+
dir("${env.WORKSPACE}@tmp") {
99+
deleteDir()
100+
}
101+
}
102+
}
103+
}
104+
}
105+
106+
post {
107+
success {
108+
echo "All node cleanups completed successfully"
109+
}
110+
failure {
111+
echo "Node cleanup failed - check the failed stage logs for details"
112+
// Generate a message to send to Slack.
113+
script {
114+
def channelName = "simsci-ci-status"
115+
def slackID = "channel"
116+
def slackMessage = """
117+
Job: *${env.JOB_NAME}*
118+
Build number: #${env.BUILD_NUMBER}
119+
Build status: *${currentBuild.result}*
120+
Author: @${slackID}
121+
Build details: <${env.BUILD_URL}/console|See in web console>
122+
""".stripIndent()
123+
124+
slackSend channel: "#${channelName}",
125+
message: slackMessage,
126+
teamDomain: "ihme",
127+
tokenCredentialId: "slack"
128+
}
129+
}
130+
}
131+
}
132+
133+
def cleanDirs(cleanupType) {
134+
echo "Starting ${cleanupType} cleanup on node: ${env.NODE_NAME} (${env.NODE_LABELS})"
135+
136+
// Determine which directories to clean based on cleanup type
137+
def dirsToClean = cleanupType == "shared" ? env.DIRS_TO_CLEAN_SHARED : env.DIRS_TO_CLEAN_PER_NODE
138+
139+
// Split the directories and loop through them
140+
def dirList = dirsToClean.split(',')
141+
142+
// Special case: built-in node doesn't have /opt/jenkins/workspace
143+
if (env.NODE_NAME == "built-in" && cleanupType == "per-node") {
144+
dirList = dirList.findAll { it != "/opt/jenkins/workspace" }
145+
}
146+
147+
for (dir in dirList) {
148+
sh """
149+
#!/bin/bash
150+
151+
set -e # Fail fast on errors
152+
153+
# Safety checks before attempting cleanup
154+
if [ -z "${dir}" ]; then
155+
echo "ERROR: Empty directory path, skipping"
156+
exit 1
157+
fi
158+
159+
if [ "${dir}" = "/" ]; then
160+
echo "ERROR: Refusing to clean root directory /, skipping"
161+
exit 1
162+
fi
163+
164+
if [ ! -d "${dir}" ]; then
165+
echo "ERROR: Directory ${dir} does not exist or is not accessible, skipping"
166+
exit 1
167+
fi
168+
169+
echo "----------------------------------------"
170+
echo "Running ${cleanupType} cleanup on \$(hostname):${dir}"
171+
172+
# Remove directories (excluding this build's 'cleanup*' dirs)
173+
echo "Listing (non-cleanup) directories in ${dir} older than ${env.DAYS_OLD} days:"
174+
find "${dir}" -mindepth 1 -maxdepth 1 -mtime +${env.DAYS_OLD} -type d ! -name 'cleanup*'
175+
176+
echo "Deleting (non-cleanup) directories:"
177+
find "${dir}" -mindepth 1 -maxdepth 1 -mtime +${env.DAYS_OLD} -type d ! -name 'cleanup*' -exec rm -rf {} + || echo "Some directories could not be deleted due to permissions"
178+
179+
# Remove files
180+
echo "Listing files in ${dir} older than ${env.DAYS_OLD} days:"
181+
find "${dir}" -mindepth 1 -maxdepth 1 -mtime +${env.DAYS_OLD} -type f
182+
183+
echo "Deleting files:"
184+
find "${dir}" -mindepth 1 -maxdepth 1 -mtime +${env.DAYS_OLD} -type f -exec rm -f {} + || echo "Some files could not be deleted due to permissions"
185+
186+
echo "Cleanup completed for ${dir}"
187+
"""
188+
}
189+
190+
echo "${cleanupType} cleanup completed successfully on ${env.NODE_NAME}"
191+
}

0 commit comments

Comments
 (0)