๐งน How to disable automatic cleanup in jenkins?
Jenkins workspace
์ ํจ์ค(Jenkins) ์์๋ ๊ฐ๊ฐ์ job build process ๋ง๋ค ๊ณ ์ ํ workspace ์ ์์ฑํ์ฌ ์ฌ์ฉํฉ๋๋ค.
workspace ์๋ build ์ ํ์ํ ํ์ผ๋ค์ด ์ ์ฅ๋๋ฉฐ,
์ฌ๋ฌ ๋ฒ์ ์คํ์๋ ๋ ๋ฆฝ์ ์ธ ํ๊ฒฝ์์ build ๊ฐ ๊ฐ๋ฅํ๋๋ก ์ ๊ณตํด์ค๋๋ค.
workspace ์ ์ ์ฌ๋๋ ํ์ผ์ ํฌ๊ธฐ๊ฐ ํฐ ๊ฒฝ์ฐ,
jenkins server ์ disk ๊ฐ ๊ฐ๋ ์ฐฐ ์ ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด,
ํ์ดํ๋ผ์ธ์ cleanWs()
๋ช
๋ น์ด๋ฅผ ์ถ๊ฐํ์ฌ ๊ฐ build process ๋ง๋ค workspace ๋ฅผ ์ง์์ฃผ๋ ์์
์ ์ ํ/ํํํ๋๋ก ์ค์ ํ ์ ์์ฃ .
workspace ๋ฅผ ์ ์งํ๊ณ ์ถ๋ค๋ฉด cleanWs()
๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด ๋ ๊ฒ๋ง ๊ฐ์ง๋ง,
์ค์ ๋ก๋ ์ผ์ ์ฃผ๊ธฐ๊ฐ ์ง๋๋ฉด ์ค๋๋ workspace ๋ ์ค์ค๋ก ์ ๊ฑฐ๋ฉ๋๋ค.
์ด์ ํ๊ฒฝ์์ ๋์ํ๊ณ ์๋ jenkins job ์ค ์ผ๋ถ๋ ํ์ดํ๋ผ์ธ์ cleanWs() ๋ฅผ ์ฌ์ฉํ๊ณ ์์ง ์์์ต๋๋ค.
๊ทธ๋ผ์๋ console log ๋ฅผ ๋ณด๋ฉด clean workspace ๋ฅผ ์๋ํ ๊ฒ์ ํ์ธํ ์ ์์์ฃ .
์ ์ด๋ ๊ฒ ๋์ํ๋ ์ง, ์ดํด๋ณด์์ต๋๋ค.
WorkspaceCleanupThread
์์นํด๋ณด๋ ์ ํจ์ค ์์คํ ๋ด์์ ์ฃผ๊ธฐ์ ์ผ๋ก workspace ๋ฅผ cleanup ํ์ฌ, ์ ํจ์ค ์๋ฒ์ disk ๊ณต๊ฐ์ ๊ด๋ฆฌํ๋ค๊ณ ํฉ๋๋ค.
๊ด๋ จ ์ธ๋ถ ๋ก์ง์ WorkspaceCleanupThread.java
์์ ํ์ธํ ์ ์์์ต๋๋ค.
์ฃผ์๊น๊ฒ ํ์ธํด์ผ ํ๋ ๋ถ๋ถ์๋ โญ๏ธ์ด๋ชจ์ง๋ฅผ ๋ฌ์๋์์ต๋๋ค.
/**
* Clean up old left-over workspaces from agents.
*
* @author Kohsuke Kawaguchi
*/
@Extension @Symbol("workspaceCleanup")
public class WorkspaceCleanupThread extends AsyncPeriodicWork {
// ... ์๋ต ...
@Override protected void execute(TaskListener listener) throws InterruptedException, IOException {
if (disabled) { <------ โญ๏ธ
LOGGER.fine("Disabled. Skipping execution");
return;
}
// ... ์๋ต ...
for (TopLevelItem item : j.allItems(TopLevelItem.class)) {
if (item instanceof ModifiableTopLevelItemGroup) { // no such thing as TopLevelItemGroup, and ItemGroup offers no access to its type parameter
continue; // children will typically have their own workspaces as subdirectories; probably no real workspace of its own
}
listener.getLogger().println("Checking " + item.getFullDisplayName());
for (Node node : nodes) {
FilePath ws = node.getWorkspaceFor(item);
if (ws == null) {
continue; // offline, fine
}
boolean check;
try {
check = shouldBeDeleted(item, ws, node); <------ โญ๏ธ
} catch (IOException | InterruptedException x) {
Functions.printStackTrace(x, listener.error("Failed to check " + node.getDisplayName()));
continue;
}
if (check) { <------ โญ๏ธ
listener.getLogger().println("Deleting " + ws + " on " + node.getDisplayName());
try {
ws.deleteRecursive(); <------ โญ๏ธ
WorkspaceList.tempDir(ws).deleteRecursive(); <------ โญ๏ธ
} catch (IOException | InterruptedException x) {
Functions.printStackTrace(x, listener.error("Failed to delete " + ws + " on " + node.getDisplayName()));
}
}
}
}
}
private boolean shouldBeDeleted(@Nonnull TopLevelItem item, FilePath dir, @Nonnull Node n) throws IOException, InterruptedException {
// ... ์๋ต ...
if(dir.lastModified() + retainForDays * DAY > now) { <------ โญ๏ธ
LOGGER.log(Level.FINE, "Directory {0} is only {1} old, so not deleting", new Object[] {dir, Util.getTimeSpanString(now-dir.lastModified())});
return false;
}
// ... ์๋ต ...
return true;
}
/**
* Can be used to disable workspace clean up. <------ โญ๏ธ
*/
public static boolean disabled = SystemProperties.getBoolean(WorkspaceCleanupThread.class.getName()+".disabled");
/**
* How often the clean up should run. This is final as Jenkins will not reflect changes anyway. <------ โญ๏ธ
*/
public static final int recurrencePeriodHours = SystemProperties.getInteger(WorkspaceCleanupThread.class.getName()+".recurrencePeriodHours", 24);
/**
* Number of days workspaces should be retained. <------ โญ๏ธ
*/
public static int retainForDays = SystemProperties.getInteger(WorkspaceCleanupThread.class.getName()+".retainForDays", 30);
}
์ ์ฝ๋๋ฅผ ํตํด ์ ์ ์๋ ์ ์ ์ ๋ฆฌํด๋ณด์์ต๋๋ค.
- recurrencePeriodHours ์ฃผ๊ธฐ๋ง๋ค workspace clean up ์ ์ํ (๊ธฐ๋ณธ๊ฐ: 24 ์๊ฐ)
- ์ญ์ ํด์ผ ํ workspace ๋ฅผ ํ๋จํ๋ ๊ธฐ์ค์, ๋ง์ง๋ง ์์ ์๊ฐ์ด retainForDays ๋ณด๋ค ์ค๋๋์๋์ง๋ฅผ ์ฒดํฌ (๊ธฐ๋ณธ๊ฐ: 30 ์ผ)
์ ํจ์ค job ํ์ดํ๋ผ์ธ์์ cleanWs() ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ผ๋, ์ ํจ์ค ์๋ฒ์์ workspace ๋ฅผ clean up ํ๋ ค๊ณ ํ ์ด์ ๋ ์ด์ ๋ถ๋ช ํด์ก์ฃ .
๋ง์ฝ, WorkspaceCleanupThread ์ ์ํ workspace clean up ์ด ์ผ์ด๋์ง ์๋๋ก ๋ฐฉ์งํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
WorkspaceCleanupThread.java
์ฝ๋๋ฅผ ๋ค์ ํ์ธํด๋ด
์๋ค.
@Override protected void execute(TaskListener listener) throws InterruptedException, IOException {
if (disabled) { <------ โญ๏ธ
LOGGER.fine("Disabled. Skipping execution");
return;
}
// ... ์๋ต ...
}
/**
* Can be used to disable workspace clean up. <------ โญ๏ธ
*/
public static boolean disabled = SystemProperties.getBoolean(WorkspaceCleanupThread.class.getName()+".disabled");
disabled
๊ฐ์ ๋ฐ๋ผ์ ๋ก์ง์ด ์ํ๋๋ ๊ฒ์ ์ ์ ์๊ณ , ํด๋น ๊ฐ์ ํ๊ฒฝ ๋ณ์๋ก ์ ๋ฌ๋ฐ์ผ๋ฏ๋ก
Jenkins ์์ ์,
-Dhudson.model.WorkspaceCleanupThread.disable=true
๋ฅผ ์ถ๊ฐํ์ฌ workspace clean up ์ ๋นํ์ฑํ ํ ์ ์์ต๋๋ค.
์๋ชป๋ ๋ถ๋ถ์ด ์๋ค๋ฉด comment ๋จ๊ฒจ์ฃผ์ธ์!
Leave a comment