:return: a dict of available containers in the form
        {
            "name": {                          #for example, "default"
                "id": "container img id",      #             "sha256:715c5cb5575cdb2641956e42af4a53e69edf763ce701006b2c6e0f4f39b68dd3"
                "created": 12345678            # create date
                "ports": [22, 434]             # list of ports needed
            }
        }

def get_containers(self):
        """
        :return: a dict of available containers in the form
        {
            "name": {                          #for example, "default"
                "id": "container img id",      #             "sha256:715c5cb5575cdb2641956e42af4a53e69edf763ce701006b2c6e0f4f39b68dd3"
                "created": 12345678            # create date
                "ports": [22, 434]             # list of ports needed
            }
        }
        """

        # First, create a dict with {"id": {"title": "alias", "created": 000, "ports": [0, 1]}}
        images = {}
        for x in self._docker.images.list(filters={"label": "org.inginious.grading.name"}):
            try:
                title = x.labels["org.inginious.grading.name"]
                created = datetime.strptime(x.attrs['Created'][:-4], "%Y-%m-%dT%H:%M:%S.%f").timestamp()
                ports = [int(y) for y in x.labels["org.inginious.grading.ports"].split(
                    ",")] if "org.inginious.grading.ports" in x.labels else []
                images[x.attrs['Id']] = {"title": title, "created": created, "ports": ports}
            except:
                logging.getLogger("inginious.agent").exception("Container %s is badly formatted", title)

        # Then, we keep only the last version of each name
        latest = {}
        for img_id, img_c in images.items():
            if img_c["title"] not in latest or latest[img_c["title"]]["created"] < img_c["created"]:
                latest[img_c["title"]] = {"id": img_id, "created": img_c["created"], "ports": img_c["ports"]}
        return latest