From 7a9395ce23ff8bbe27f009ff841ce73fb3e3d1ae Mon Sep 17 00:00:00 2001
From: Lisa Zangrando <lisa.zangrando@pd.infn.it>
Date: Wed, 20 Sep 2017 10:09:53 +0200
Subject: [PATCH] Restored setQuotaTypeServer()

This commit restores the method setQuotaTypeServer() which set the
server type as metadata.

Change-Id: I09dfafdbe73d59eb43c09c79a50a5449e63833e4
Sem-Ver: bugfix
---
 synergy_scheduler_manager/common/queue.py     |  1 -
 synergy_scheduler_manager/common/quota.py     |  2 +-
 synergy_scheduler_manager/nova_manager.py     | 27 ++++++++++++++
 synergy_scheduler_manager/project_manager.py  |  1 +
 synergy_scheduler_manager/quota_manager.py    | 35 +++----------------
 .../scheduler_manager.py                      | 30 ++++++++--------
 6 files changed, 49 insertions(+), 47 deletions(-)

diff --git a/synergy_scheduler_manager/common/queue.py b/synergy_scheduler_manager/common/queue.py
index c0d8657..353f0c3 100644
--- a/synergy_scheduler_manager/common/queue.py
+++ b/synergy_scheduler_manager/common/queue.py
@@ -229,7 +229,6 @@ class Queue(SynergyObject):
                 heapq.heappush(self._items, (-item.getPriority(),
                                              item.getCreationTime(), item))
 
-                self._incSize(1)
             self.condition.notifyAll()
 
     def getType(self):
diff --git a/synergy_scheduler_manager/common/quota.py b/synergy_scheduler_manager/common/quota.py
index fbeeccd..34fbd8f 100644
--- a/synergy_scheduler_manager/common/quota.py
+++ b/synergy_scheduler_manager/common/quota.py
@@ -24,7 +24,7 @@ See the License for the specific language governing
 permissions and limitations under the License."""
 
 
-LOG = logging.getLogger("quota")
+LOG = logging.getLogger(__name__)
 
 
 class Quota(SynergyObject):
diff --git a/synergy_scheduler_manager/nova_manager.py b/synergy_scheduler_manager/nova_manager.py
index dc9d175..b4d1ddc 100644
--- a/synergy_scheduler_manager/nova_manager.py
+++ b/synergy_scheduler_manager/nova_manager.py
@@ -685,6 +685,33 @@ class NovaManager(Manager):
 
         return response_data
 
+    def setQuotaTypeServer(self, server):
+        if not server:
+            return
+
+        QUERY = "insert into nova.instance_metadata (created_at, `key`, " \
+            "`value`, instance_uuid) values (%s, 'quota', %s, %s)"
+
+        connection = self.db_engine.connect()
+        trans = connection.begin()
+
+        quota_type = "private"
+
+        if server.isEphemeral():
+            quota_type = "shared"
+
+        try:
+            connection.execute(QUERY,
+                               [server.getCreatedAt(), quota_type,
+                                server.getId()])
+
+            trans.commit()
+        except SQLAlchemyError as ex:
+            trans.rollback()
+            raise SynergyError(ex.message)
+        finally:
+            connection.close()
+
     def getHosts(self):
         data = {}
         url = "os-hosts"
diff --git a/synergy_scheduler_manager/project_manager.py b/synergy_scheduler_manager/project_manager.py
index 84d8b1f..db66180 100644
--- a/synergy_scheduler_manager/project_manager.py
+++ b/synergy_scheduler_manager/project_manager.py
@@ -378,3 +378,4 @@ NOT NULL PRIMARY KEY, name VARCHAR(64), share INT DEFAULT 0, TTL INT DEFAULT \
             raise SynergyError(ex.message)
         finally:
             connection.close()
+            self.notify(event_type="PROJECT_DONE")
diff --git a/synergy_scheduler_manager/quota_manager.py b/synergy_scheduler_manager/quota_manager.py
index 0051a58..35b7bb3 100644
--- a/synergy_scheduler_manager/quota_manager.py
+++ b/synergy_scheduler_manager/quota_manager.py
@@ -37,8 +37,6 @@ class QuotaManager(Manager):
         super(QuotaManager, self).__init__("QuotaManager")
 
     def setup(self):
-        self.projects = {}
-
         if self.getManager("NovaManager") is None:
             raise SynergyError("NovaManager not found!")
 
@@ -142,8 +140,7 @@ class QuotaManager(Manager):
                                         project.getName(),
                                         project.getId()))
                             quota.allocate(server)
-
-                self.projects[project.getId()] = project
+                self.updateSharedQuota()
             except SynergyError as ex:
                 LOG.error(ex)
                 raise ex
@@ -254,34 +251,12 @@ class QuotaManager(Manager):
             kprojects = self.keystone_manager.getProjects(domain_id=dom_id)
 
             for kproject in kprojects:
-                project = self.project_manager.getProject(id=kproject.getId())
+                quota = self.nova_manager.getQuota(kproject.getId())
 
-                if project:
-                    quota = self.nova_manager.getQuota(project.getId(),
+                if quota.getSize("vcpus") == -1 and\
+                        quota.getSize("memory") == -1:
+                    quota = self.nova_manager.getQuota(kproject.getId(),
                                                        is_class=True)
-                    pquota = project.getQuota()
-                    vcpus_size = quota.getSize("vcpus")
-                    vcpus_usage = pquota.getUsage("vcpus")
-                    mem_size = quota.getSize("memory")
-                    mem_usage = pquota.getUsage("memory")
-
-                    if vcpus_usage > vcpus_size or mem_usage > mem_size:
-                        LOG.info("cannot shrink the private quota for project"
-                                 " %r (id=%s) because the usage of current "
-                                 "quota exceeds the new size (vcpus=%s, "
-                                 "memory=%s)" % (project.getName(),
-                                                 project.getId(),
-                                                 quota.getSize("vcpus"),
-                                                 quota.getSize("memory")))
-                        self.nova_manager.updateQuota(pquota, is_class=True)
-                        quota = pquota
-                    else:
-                        pquota.setSize("vcpus", value=quota.getSize("vcpus"))
-                        pquota.setSize("memory", value=quota.getSize("memory"))
-                        pquota.setSize("instances",
-                                       value=quota.getSize("instances"))
-                else:
-                    quota = self.nova_manager.getQuota(kproject.getId())
 
                 if quota.getSize("vcpus") > 0:
                     static_vcpus += quota.getSize("vcpus")
diff --git a/synergy_scheduler_manager/scheduler_manager.py b/synergy_scheduler_manager/scheduler_manager.py
index eb15e2d..d7389a1 100644
--- a/synergy_scheduler_manager/scheduler_manager.py
+++ b/synergy_scheduler_manager/scheduler_manager.py
@@ -74,6 +74,10 @@ class Worker(Thread):
                     while queue_items:
                         self.queue.restore(queue_items.pop(0))
 
+                    for project in self.project_manager.getProjects():
+                        for user in project.getUsers():
+                            self.queue.updatePriority(user)
+
                 if len(queue_items) >= self.backfill_depth:
                     SharedQuota.wait()
                     continue
@@ -213,8 +217,6 @@ class SchedulerManager(Manager):
         if self.configured:
             return
 
-        self.quota_manager.updateSharedQuota()
-
         try:
             self.queue = self.queue_manager.createQueue("DYNAMIC", "PRIORITY")
         except SynergyError as ex:
@@ -232,7 +234,6 @@ class SchedulerManager(Manager):
                         self.nova_manager,
                         self.keystone_manager,
                         self.backfill_depth)
-        worker.start()
 
         self.workers.append(worker)
 
@@ -268,6 +269,10 @@ class SchedulerManager(Manager):
             if self.queue:
                 self.queue.updatePriority(kwargs.get("user", None))
 
+        elif event_type == "PROJECT_DONE":
+            for worker in self.workers:
+                worker.start()
+
     def _processServerEvent(self, server, event, state):
         project = self.project_manager.getProject(id=server.getProjectId())
 
@@ -298,21 +303,14 @@ class SchedulerManager(Manager):
                     LOG.warn("cannot release server %s "
                              "(reason=%s)" % (server.getId(), ex))
             elif state == "error":
-                LOG.info("error occurred on server %s (host %s)"
-                         % (server.getId(), server.getHost()))
-
                 if not server.getTerminatedAt() and not server.getDeletedAt():
                     try:
-                        self.nova_manager.deleteServer(server)
-                    except Exception as ex:
-                        LOG.error("cannot delete server %s: %s"
-                                  % (server.getId(), ex))
+                        LOG.info("error occurred on server %s (host %s)"
+                                 % (server.getId(), server.getHost()))
 
-                try:
-                    quota.release(server)
-                except Exception as ex:
-                    LOG.warn("cannot release server %s "
-                             "(reason=%s)" % (server.getId(), ex))
+                        self.nova_manager.deleteServer(server)
+                    except Exception:
+                        pass
 
     def _processServerCreate(self, request):
         server = request.getServer()
@@ -339,6 +337,8 @@ class SchedulerManager(Manager):
                                 request.getProjectId(), num_attempts, reason))
                     return
 
+                self.nova_manager.setQuotaTypeServer(server)
+
                 if server.isPermanent():
                     if quota.allocate(server, blocking=False):
                         LOG.info("new request: id=%s user_id=%s prj_id=%s "