Skip to content

Commit

Permalink
Merge pull request #159 from flyingcircusio/batou-424-symlink-and-cle…
Browse files Browse the repository at this point in the history
…anup-add-systemd-run-task

Add systemd-run cleanup option for SymlinkAndCleanup removals
  • Loading branch information
zagy authored Apr 16, 2024
2 parents 52d3ce1 + f2be6ff commit f131b4c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!--
A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->
Add systemd-run async cleanup option for SymlinkAndCleanup removals
48 changes: 39 additions & 9 deletions src/batou_ext/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import os.path
import shutil
import subprocess
import urllib.parse

import batou
Expand All @@ -25,6 +26,8 @@ class SymlinkAndCleanup(batou.component.Component):

prefix = None

use_systemd_run_async_cleanup = False

def configure(self):
self._current_link = (
f"{self.prefix}-current" if self.prefix else "current"
Expand Down Expand Up @@ -97,13 +100,40 @@ def update(self):
if current:
batou.output.annotate("last -> {}".format(current))
os.symlink(current, self._last_link)
for el in self._list_removals():
batou.output.annotate("Removing: {}".format(el))
candidates = self._list_removals()
if self.use_systemd_run_async_cleanup:
# spawns a IOPS limited systemd-run cleanup job
try:
if os.path.isdir(el):
shutil.rmtree(el)
else:
os.remove(el)
except OSError as e:
batou.output.error(f'Failed to remove "{el}": {e.strerror}')
pass
batou.output.annotate(
"Removing using systemd-run: {}".format(candidates)
)
rm_cmd = [
"rm",
"-rf",
*candidates, # consider: ARG_MAX is limited
]
subprocess.run(
[
"systemd-run",
"--unit",
f"batou-cleanup-{self.prefix}",
"--property=IOReadIOPSMax=100",
"--property=IOWriteIOPSMax=100",
*rm_cmd,
],
check=True,
)
except subprocess.CalledProcessError as e:
batou.output.error(f"Failed to remove: {e}")
else:
for el in candidates:
batou.output.annotate("Removing: {}".format(el))
try:
if os.path.isdir(el):
shutil.rmtree(el)
else:
os.remove(el)
except OSError as e:
batou.output.error(
f'Failed to remove "{el}": {e.strerror}'
)

0 comments on commit f131b4c

Please sign in to comment.