Fix bug 1263
[osm/N2VC.git] / n2vc / libjuju.py
index a457309..4702414 100644 (file)
@@ -81,9 +81,12 @@ class Libjuju:
         self.log = log or logging.getLogger("Libjuju")
         self.db = db
         db_endpoints = self._get_api_endpoints_db()
-        self.endpoints = db_endpoints or [endpoint]
-        if db_endpoints is None:
+        self.endpoints = None
+        if (db_endpoints and endpoint not in db_endpoints) or not db_endpoints:
+            self.endpoints = [endpoint]
             self._update_api_endpoints_db(self.endpoints)
+        else:
+            self.endpoints = db_endpoints
         self.api_proxy = api_proxy
         self.username = username
         self.password = password
@@ -104,7 +107,10 @@ class Libjuju:
         self.models = set()
         self.log.debug("Libjuju initialized!")
 
-        self.health_check_task = self.loop.create_task(self.health_check())
+        self.health_check_task = self._create_health_check_task()
+
+    def _create_health_check_task(self):
+        return self.loop.create_task(self.health_check())
 
     async def get_controller(self, timeout: float = 5.0) -> Controller:
         """
@@ -817,6 +823,10 @@ class Libjuju:
             self.log.debug("Destroying model {}".format(model_name))
             uuid = model.info.uuid
 
+            # Destroy machines that are manually provisioned
+            # and still are in pending state
+            await self._destroy_pending_machines(model, only_manual=True)
+
             # Disconnect model
             await self.disconnect_model(model)
 
@@ -864,6 +874,23 @@ class Libjuju:
         else:
             self.log.warning("Application not found: {}".format(application_name))
 
+    async def _destroy_pending_machines(self, model: Model, only_manual: bool = False):
+        """
+        Destroy pending machines in a given model
+
+        :param: only_manual:    Bool that indicates only manually provisioned
+                                machines should be destroyed (if True), or that
+                                all pending machines should be destroyed
+        """
+        status = await model.get_status()
+        for machine_id in status.machines:
+            machine_status = status.machines[machine_id]
+            if machine_status.agent_status.status == "pending":
+                if only_manual and not machine_status.instance_id.startswith("manual:"):
+                    break
+                machine = model.machines[machine_id]
+                await machine.destroy(force=True)
+
     # async def destroy_machine(
     #     self, model: Model, machine_id: str, total_timeout: float = 3600
     # ):