From: Tony Mack Date: Wed, 7 May 2014 01:42:36 +0000 (-0400) Subject: sync images across deployments X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=bf39d9fcc245717369dc938fc47db69be6e4ac08;p=plstackapi.git sync images across deployments --- diff --git a/planetstack/core/models/image.py b/planetstack/core/models/image.py index b4803e2..db01e1b 100644 --- a/planetstack/core/models/image.py +++ b/planetstack/core/models/image.py @@ -1,13 +1,23 @@ import os from django.db import models from core.models import PlCoreBase +from core.models import Deployment # Create your models here. class Image(PlCoreBase): - image_id = models.CharField(max_length=256, unique=True) name = models.CharField(max_length=256, unique=True) disk_format = models.CharField(max_length=256) container_format = models.CharField(max_length=256) + path = models.CharField(max_length=256, null=True, blank=True, help_text="Path to image on local disk") def __unicode__(self): return u'%s' % (self.name) + +class ImageDeployments(PlCoreBase): + image = models.ForeignKey(Image) + deployment = models.ForeignKey(Deployment) + glance_image_id = models.CharField(null=True, blank=True, max_length=200, help_text="Glance image id") + + def __unicode__(self): return u'%s %s' % (self.image, self.deployment) + + diff --git a/planetstack/observer/steps/__init__.py b/planetstack/observer/steps/__init__.py index eabf46c..2ef6922 100644 --- a/planetstack/observer/steps/__init__.py +++ b/planetstack/observer/steps/__init__.py @@ -12,4 +12,5 @@ from .sync_users import SyncUsers from .sync_roles import SyncRoles from .sync_nodes import SyncNodes from .sync_images import SyncImages +from .sync_image_deployments import SyncImageDeployments from .garbage_collector import GarbageCollector diff --git a/planetstack/observer/steps/sync_image_deployments.py b/planetstack/observer/steps/sync_image_deployments.py new file mode 100644 index 0000000..e611044 --- /dev/null +++ b/planetstack/observer/steps/sync_image_deployments.py @@ -0,0 +1,44 @@ +import os +import base64 +from collections import defaultdict +from django.db.models import F, Q +from planetstack.config import Config +from observer.openstacksyncstep import OpenStackSyncStep +from core.models.deployment import Deployment +from core.models.image import Image, ImageDeployments + +class SyncImageDeployments(OpenStackSyncStep): + provides=[ImageDeployments] + requested_interval=0 + + def fetch_pending(self): + # ensure images are available across all deployments + image_deployments = ImageDeployments.objects.all() + image_deploy_lookup = defaultdict(list) + for image_deployment in image_deployments: + image_deploy_lookup[image_deployment.image].append(image_deployment.deployment) + + all_deployments = Deployment.objects.all() + for image in Image.objects.all(): + expected_deployments = all_deployments + for expected_deployment in expected_deployments: + if image not in image_deploy_lookup or \ + expected_deployment not in image_deploy_lookup[image]: + id = ImageDeployments(image=image, deployment=expected_deployment) + id.save() + + # now we return all images that need to be enacted + return ImageDeployments.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) + + def sync_record(self, image_deployment): + driver = self.driver.admin_driver(deployment=image_deployment.deployment.name) + image = { + 'name': image_deployment.image.name, + 'is_public': True, + 'disk_format': 'raw', + 'container_format': 'bare', + 'file': image_deployment.image.path, + } + glance_image = driver.shell.glance.add_image(image) + image_deployment.glance_image_id = glance_image['id'] + image_deployment.save() diff --git a/planetstack/observer/steps/sync_images.py b/planetstack/observer/steps/sync_images.py index 2dbd74d..6ee53fe 100644 --- a/planetstack/observer/steps/sync_images.py +++ b/planetstack/observer/steps/sync_images.py @@ -10,20 +10,28 @@ class SyncImages(OpenStackSyncStep): requested_interval=0 def fetch_pending(self): + # get list of images on disk + images_path = Config().observer_images_directory + available_images = {} + for f in os.listdir(images_path): + if os.path.isfile(os.path.join(images_path ,f)): + available_images[f] = os.path.join(images_path ,f) + images = Image.objects.all() image_names = [image.name for image in images] + + for image_name in available_images: + #remove file extension + clean_name = ".".join(image_name.split('.')[:-1]) + if image_name not in image_names: + image = Image(name=clean_name, + disk_format='raw', + container_format='bare', + path = available_images[image_name]) + image.save() - new_images = [] - glance_images = self.driver.shell.glance.get_images() - for glance_image in glance_images: - if glance_image['name'] not in image_names: - image = Image(image_id=glance_image['id'], - name=glance_image['name'], - disk_format=glance_image['disk_format'], - container_format=glance_image['container_format']) - new_images.append(image) - - return new_images + + return Image.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) def sync_record(self, image): image.save()