From 8023fdefdc6c24a75e96707ed8658d000d9b43d5 Mon Sep 17 00:00:00 2001
From: Tomas Kopecek <tkopecek@redhat.com>
Date: Mar 16 2020 12:25:39 +0000
Subject: [PATCH 1/4] delete oldest failed buildroot, when there is no space


Fixes: https://pagure.io/koji/issue/1913

---

diff --git a/koji/daemon.py b/koji/daemon.py
index 0167c5b..99cdf4c 100644
--- a/koji/daemon.py
+++ b/koji/daemon.py
@@ -683,7 +683,8 @@ class TaskManager(object):
             # index
             missed_br = dict([(row['id'], row) for row in missed_br])
             tasks = dict([(row['id'], row) for row in self.session.getTaskInfo(tasks)])
-            for id in local_only:
+            # go from +- oldest
+            for id in sorted(local_only):
                 # Cleaning options
                 #   - wait til later
                 #   - "soft" clean (leaving empty root/ dir)
@@ -708,8 +709,13 @@ class TaskManager(object):
                             age < self.options.failed_buildroot_lifetime:
                         # XXX - this could be smarter
                         # keep buildroots for failed tasks around for a little while
-                        self.logger.debug("Keeping failed buildroot: %s" % desc)
-                        continue
+                        fs_stat = os.statvfs(self.options.mockdir)
+                        available = fs_stat.f_bavail * fs_stat.f_bsize
+                        availableMB = available // 1024 // 1024
+                        if availableMB > self.options.minspace:
+                            # we can leave it in place, otherwise delete it
+                            self.logger.debug("Keeping failed buildroot: %s" % desc)
+                            continue
                 topdir = data['dir']
                 rootdir = None
                 if topdir:

From f95a3a3cccfd7337611e71f23ead46f77cf890fc Mon Sep 17 00:00:00 2001
From: Tomas Kopecek <tkopecek@redhat.com>
Date: Mar 24 2020 12:43:27 +0000
Subject: [PATCH 2/4] add real delete


---

diff --git a/koji/daemon.py b/koji/daemon.py
index 99cdf4c..1976ed9 100644
--- a/koji/daemon.py
+++ b/koji/daemon.py
@@ -691,6 +691,7 @@ class TaskManager(object):
                 #   - full removal
                 data = local_br[id]
                 br = missed_br.get(id)
+                lack_of_space = False
                 if not br:
                     self.logger.warn("%(name)s: not in db" % data)
                     continue
@@ -716,6 +717,8 @@ class TaskManager(object):
                             # we can leave it in place, otherwise delete it
                             self.logger.debug("Keeping failed buildroot: %s" % desc)
                             continue
+                        else:
+                            lack_of_space = True
                 topdir = data['dir']
                 rootdir = None
                 if topdir:
@@ -735,7 +738,7 @@ class TaskManager(object):
                 # can lead to a world of hurt.
                 # We remove the rootdir contents but leave the rootdir unless it
                 # is really old
-                if age > 3600 * 24:
+                if age > 3600 * 24 or lack_of_space:
                     # dir untouched for a day
                     self.logger.info("Removing buildroot: %s" % desc)
                     if topdir and safe_rmtree(topdir, unmount=True, strict=False) != 0:

From f041fd32e0f45204af0686fa9b6e91992da1b774 Mon Sep 17 00:00:00 2001
From: Tomas Kopecek <tkopecek@redhat.com>
Date: Mar 24 2020 15:55:16 +0000
Subject: [PATCH 3/4] delete main part of data


---

diff --git a/koji/daemon.py b/koji/daemon.py
index 1976ed9..e031c35 100644
--- a/koji/daemon.py
+++ b/koji/daemon.py
@@ -691,7 +691,6 @@ class TaskManager(object):
                 #   - full removal
                 data = local_br[id]
                 br = missed_br.get(id)
-                lack_of_space = False
                 if not br:
                     self.logger.warn("%(name)s: not in db" % data)
                     continue
@@ -710,15 +709,10 @@ class TaskManager(object):
                             age < self.options.failed_buildroot_lifetime:
                         # XXX - this could be smarter
                         # keep buildroots for failed tasks around for a little while
-                        fs_stat = os.statvfs(self.options.mockdir)
-                        available = fs_stat.f_bavail * fs_stat.f_bsize
-                        availableMB = available // 1024 // 1024
-                        if availableMB > self.options.minspace:
+                        if self.checkSpace():
                             # we can leave it in place, otherwise delete it
                             self.logger.debug("Keeping failed buildroot: %s" % desc)
                             continue
-                        else:
-                            lack_of_space = True
                 topdir = data['dir']
                 rootdir = None
                 if topdir:
@@ -738,7 +732,7 @@ class TaskManager(object):
                 # can lead to a world of hurt.
                 # We remove the rootdir contents but leave the rootdir unless it
                 # is really old
-                if age > 3600 * 24 or lack_of_space:
+                if age > 3600 * 24:
                     # dir untouched for a day
                     self.logger.info("Removing buildroot: %s" % desc)
                     if topdir and safe_rmtree(topdir, unmount=True, strict=False) != 0:
@@ -748,7 +742,7 @@ class TaskManager(object):
                         os.unlink(data['cfg'])
                     except OSError as e:
                         self.logger.warn("%s: can't remove config: %s" % (desc, e))
-                elif age > 120:
+                elif age > 120 or not self.checkSpace():
                     if rootdir:
                         try:
                             flist = os.listdir(rootdir)

From 7457e31b3eaa411ac6a385284e0f37e6ca6ddf77 Mon Sep 17 00:00:00 2001
From: Tomas Kopecek <tkopecek@redhat.com>
Date: Mar 26 2020 13:30:31 +0000
Subject: [PATCH 4/4] remove unneeded condition


---

diff --git a/koji/daemon.py b/koji/daemon.py
index e031c35..316e094 100644
--- a/koji/daemon.py
+++ b/koji/daemon.py
@@ -742,7 +742,7 @@ class TaskManager(object):
                         os.unlink(data['cfg'])
                     except OSError as e:
                         self.logger.warn("%s: can't remove config: %s" % (desc, e))
-                elif age > 120 or not self.checkSpace():
+                elif age > 120:
                     if rootdir:
                         try:
                             flist = os.listdir(rootdir)

