52aaeef15fc845f8e332ca48d4dc4bb3ef29790e
[plstackapi.git] / planetstack / observer / steps / sync_image_deployments.py
1 import os
2 import base64
3 from collections import defaultdict
4 from django.db.models import F, Q
5 from planetstack.config import Config
6 from observer.openstacksyncstep import OpenStackSyncStep
7 from core.models.deployment import Deployment
8 from core.models.image import Image, ImageDeployments
9 from util.logger import Logger, logging
10 \r
11 logger = Logger(level=logging.INFO)
12
13 class SyncImageDeployments(OpenStackSyncStep):
14     provides=[ImageDeployments]
15     requested_interval=0
16
17     def fetch_pending(self):
18         # ensure images are available across all deployments
19         image_deployments = ImageDeployments.objects.all()
20         image_deploy_lookup = defaultdict(list)
21         for image_deployment in image_deployments:
22             image_deploy_lookup[image_deployment.image].append(image_deployment.deployment)
23
24         all_deployments = Deployment.objects.all()
25         for image in Image.objects.all():
26             expected_deployments = all_deployments
27             for expected_deployment in expected_deployments:
28                 if image not in image_deploy_lookup or \
29                   expected_deployment not in image_deploy_lookup[image]:
30                     id = ImageDeployments(image=image, deployment=expected_deployment)
31                     id.save()
32
33         # now we return all images that need to be enacted
34         return ImageDeployments.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
35
36     def sync_record(self, image_deployment):
37         logger.info("Working on image %s on deployment %s" % (image_deployment.image.name, image_deployment.deployment.name))
38         driver = self.driver.admin_driver(deployment=image_deployment.deployment.name)
39         images = driver.shell.glance.get_images()
40         glance_image = None
41         for image in images:
42             if image['name'] == image_deployment.image.name:
43                 glance_image = image
44                 break
45         if glance_image:
46             logger.info("Found image %s on deployment %s" % (image_deployment.image.name, image_deployment.deployment.name))
47             image_deployment.glance_image_id = glance_image['id']
48         elif image_deployment.image.path:
49             image = {
50                 'name': image_deployment.image.name,
51                 'is_public': True,
52                 'disk_format': 'raw',
53                 'container_format': 'bare',
54                 'file': image_deployment.image.path,
55             }
56
57             logger.info("Creating image %s on deployment %s" % (image_deployment.image.name, image_deployment.deployment.name))
58
59             glance_image = driver.shell.glanceclient.images.create(name=image_deployment.image.name,
60                                                                    is_public=True,
61                                                                    disk_format='raw',
62                                                                    container_format='bare')
63             glance_image.update(data=open(image_deployment.image.path, 'rb'))
64
65             # While the images returned by driver.shell.glance.get_images()
66             #   are dicts, the images returned by driver.shell.glanceclient.images.create
67             #   are not dicts. We have to use getattr() instead of [] operator.
68             if not glance_image or not getattr(glance_image,"id",None):
69                 raise Exception, "Add image failed at deployment %s" % image_deployment.deployment.name
70             image_deployment.glance_image_id = getattr(glance_image, "id")
71         image_deployment.save()