def _get_flow(self, task): try: task_input = script_utils.unpack_task_input(task) uri = script_utils.validate_location_uri( task_input.get('import_from')) kwds = { 'uri': uri, 'task_id': task.task_id, 'task_type': task.type, 'context': self.context, 'task_repo': self.task_repo, 'image_repo': self.image_repo, 'image_factory': self.image_factory } return driver.DriverManager('glance.flows', task.type, invoke_on_load=True, invoke_kwds=kwds).driver except urllib.error.URLError as exc: raise exception.ImportTaskError(message=exc.reason) except exception.BadStoreUri as exc: raise exception.ImportTaskError(message=exc.msg) except RuntimeError: raise NotImplementedError()
def _get_flow(self, task): try: task_input = script_utils.unpack_task_input(task) kwds = { 'task_id': task.task_id, 'task_type': task.type, 'context': self.context, 'task_repo': self.task_repo, 'image_repo': self.image_repo, 'image_factory': self.image_factory, 'backend': task_input.get('backend') } if self.admin_repo: kwds['admin_repo'] = self.admin_repo if task.type == "import": uri = script_utils.validate_location_uri( task_input.get('import_from')) kwds['uri'] = uri if task.type == 'api_image_import': kwds['image_id'] = task_input['image_id'] kwds['import_req'] = task_input['import_req'] return driver.DriverManager('glance.flows', task.type, invoke_on_load=True, invoke_kwds=kwds).driver except urllib.error.URLError as exc: raise exception.ImportTaskError(message=exc.reason) except (exception.BadStoreUri, exception.Invalid) as exc: raise exception.ImportTaskError(message=exc.msg) except RuntimeError: raise NotImplementedError()
def execute(self): """Create temp file into store and return path to it :param image_id: Glance Image ID """ # NOTE(jokke): We've decided to use staging area for this task as # a way to expect users to configure a local store for pre-import # works on the image to happen. # # While using any path should be "technically" fine, it's not what # we recommend as the best solution. For more details on this, please # refer to the comment in the `_ImportToStore.execute` method. try: data = script_utils.get_image_data_iter(self.uri) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error("Task %(task_id)s failed with exception %(error)s", {"error": encodeutils.exception_to_unicode(e), "task_id": self.task_id}) self._path, bytes_written = self.store.add(self.image_id, data, 0)[0:2] try: content_length = int(data.headers['content-length']) if bytes_written != content_length: msg = (_("Task %(task_id)s failed because downloaded data " "size %(data_size)i is different from expected %(" "expected)i") % {"task_id": self.task_id, "data_size": bytes_written, "expected": content_length}) raise exception.ImportTaskError(msg) except (KeyError, ValueError): pass return self._path
def _execute(self, action, file_path): self.last_status = timeutils.now() if action.image_status == "deleted": raise exception.ImportTaskError("Image has been deleted, aborting" " import.") try: action.set_image_data(file_path or self.uri, self.task_id, backend=self.backend, set_active=self.set_active, callback=self._status_callback) # NOTE(yebinama): set_image_data catches Exception and raises from # them. Can't be more specific on exceptions catched. except Exception: if self.all_stores_must_succeed: raise msg = (_("%(task_id)s of %(task_type)s failed but since " "all_stores_must_succeed is set to false, continue.") % { 'task_id': self.task_id, 'task_type': self.task_type }) LOG.warning(msg) if self.backend is not None: action.add_failed_stores([self.backend]) if self.backend is not None: action.remove_importing_stores([self.backend])
def execute(self, file_path=None): """Bringing the imported image to back end store :param image_id: Glance Image ID :param file_path: path to the image file """ # NOTE(flaper87): Let's dance... and fall # # Unfortunatelly, because of the way our domain layers work and # the checks done in the FS store, we can't simply rename the file # and set the location. To do that, we'd have to duplicate the logic # of every and each of the domain factories (quota, location, etc) # and we'd also need to hack the FS store to prevent it from raising # a "duplication path" error. I'd rather have this task copying the # image bits one more time than duplicating all that logic. # # Since I don't think this should be the definitive solution, I'm # leaving the code below as a reference for what should happen here # once the FS store and domain code will be able to handle this case. # # if file_path is None: # image_import.set_image_data(image, self.uri, None) # return # NOTE(flaper87): Don't assume the image was stored in the # work_dir. Think in the case this path was provided by another task. # Also, lets try to neither assume things nor create "logic" # dependencies between this task and `_ImportToFS` # # base_path = os.path.dirname(file_path.split("file://")[-1]) # NOTE(flaper87): Hopefully just scenarios #3 and #4. I say # hopefully because nothing prevents the user to use the same # FS store path as a work dir # # image_path = os.path.join(base_path, image_id) # # if (base_path == CONF.glance_store.filesystem_store_datadir or # base_path in CONF.glance_store.filesystem_store_datadirs): # os.rename(file_path, image_path) # # image_import.set_image_data(image, image_path, None) # NOTE(jokke): The different options here are kind of pointless as we # will need the file path anyways for our delete workflow for now. # For future proofing keeping this as is. image = self.image_repo.get(self.image_id) if image.status == "deleted": raise exception.ImportTaskError("Image has been deleted, aborting" " import.") try: image_import.set_image_data(image, file_path or self.uri, self.task_id, backend=self.backend, set_active=self.set_active) # NOTE(yebinama): set_image_data catches Exception and raises from # them. Can't be more specific on exceptions catched. except Exception: if not self.allow_failure: raise msg = (_("%(task_id)s of %(task_type)s failed but since " "allow_failure is set to true, continue.") % { 'task_id': self.task_id, 'task_type': self.task_type }) LOG.warning(msg) if self.backend is not None: failed_import = image.extra_properties.get( 'os_glance_failed_import', '').split(',') failed_import.append(self.backend) image.extra_properties['os_glance_failed_import'] = ','.join( failed_import) if self.backend is not None: importing = image.extra_properties.get( 'os_glance_importing_to_stores', '').split(',') try: importing.remove(self.backend) image.extra_properties[ 'os_glance_importing_to_stores'] = ','.join(importing) except ValueError: LOG.debug( "Store %s not found in property " "os_glance_importing_to_stores.", self.backend) # NOTE(flaper87): We need to save the image again after # the locations have been set in the image. self.image_repo.save(image)