def _get_latest_docker_status(self): """ Synchronise local Django Container models with remote Docker containers """ ps = get_docker_ps.delay() containers_docker = None try: containers_docker = ps.get(timeout=30) except celery.exceptions.TimeoutError as e: logging.exception("get_docker_ps timed out (30 seconds)") if containers_docker is None: # Apparently something is wrong with the remote docker or celery # To prevent new task creation by Containers exit beat. return docker_dict = {x['Id']: x for x in containers_docker} docker_set = set(docker_dict.keys()) # retrieve container from database container_set = set( Container.objects.values_list('docker_id', flat=True)) # Work out matching matrix # docker yes non # model x # yes 1_1 1_0 # no 0_1 0_0 # m_1_1 = container_set & docker_set m_1_0 = container_set - docker_set m_0_1 = docker_set - container_set m_0_0 = ((docker_set | container_set) - (docker_set ^ container_set) - (docker_set & container_set) ) # Update state of all matching containers container_match = m_1_1 | m_1_0 for con_id in container_match: snapshot = docker_dict[ con_id] if con_id in docker_dict else None for c in Container.objects.filter(docker_id=con_id): c.update_from_docker_snapshot(snapshot) # Call error for mismatch container_mismatch = m_0_1 | m_0_0 for container in container_mismatch: info = docker_dict[container] if ('Config' in info and 'Labels' in info['Config'] and 'type' in info['Config']['Labels']): type = info['Config']['Labels']['type'] if type in [choice[0] for choice in Container.CONTAINER_TYPE_CHOICES]: self.stderr.write( "Docker container {} not found in database!".format(container)) do_docker_remove.delay(container, force=True) else: logging.info("Found non-delft3dgt docker container, ignoring.")
def test_do_docker_remove(self, mockClient): """ Assert that the docker_remove task calls the docker client.remove_container() function """ delay = do_docker_remove.delay("id") mockClient.return_value.remove_container.assert_called_with( container="id", force=False) container, log = delay.result self.assertEqual(container, "id") self.assertEqual(log, "")
def _get_latest_docker_status(self): """ Synchronise local Django Container models with remote Docker containers """ ps = get_docker_ps.apply_async(queue='priority') # Wait until the task finished successfully # or return if waiting too long checked = 0 while not ps.successful(): sleep(1) # if things take too long, revoke the task and return checked += 1 if checked >= 30: ps.revoke() return False # task is succesful, so we're getting the result and create a set containers_docker = ps.result docker_dict = {x['Id']: x for x in containers_docker} docker_set = set(docker_dict.keys()) # retrieve container from database container_set = set( Container.objects.exclude(docker_id__exact='').values_list( 'docker_id', flat=True)) # Work out matching matrix # docker yes no # model x # yes 1_1 1_0 # no 0_1 0_0 # m_1_1 = container_set & docker_set m_1_0 = container_set - docker_set m_0_1 = docker_set - container_set m_0_0 = ((docker_set | container_set) - (docker_set ^ container_set) - (docker_set & container_set)) # Update state of all matching containers container_match = m_1_1 | m_1_0 for con_id in container_match: snapshot = docker_dict[con_id] if con_id in docker_dict else None for c in Container.objects.filter(docker_id=con_id): c.update_from_docker_snapshot(snapshot) # Call error for mismatch container_mismatch = m_0_1 | m_0_0 for container in container_mismatch: info = docker_dict[container] if ('Config' in info and 'Labels' in info['Config'] and 'type' in info['Config']['Labels']): type = info['Config']['Labels']['type'] choices = Container.CONTAINER_TYPE_CHOICES if type in [choice[0] for choice in choices]: msg = "Docker container {} not found in database!".format( container) self.stderr.write(msg) do_docker_remove.delay(container, force=True) else: logging.info("Found non-delft3dgt docker container, ignoring.") return True # successful