def create_image(self, prepare_template, base, size, *args, **kwargs):
        filename = self._get_lock_name(base)

        @utils.synchronized(filename, external=True, lock_path=self.lock_path)
        def copy_raw_image(base, target, size):
            libvirt_utils.copy_image(base, target)
            if size:
                # class Raw is misnamed, format may not be 'raw' in all cases
                image = imgmodel.LocalFileImage(target,
                                                self.driver_format)
                disk.extend(image, size)

        generating = 'image_id' not in kwargs
        if generating:
            if not self.check_image_exists():
                # Generating image in place
                prepare_template(target=self.path, *args, **kwargs)
        else:
            if not os.path.exists(base):
                prepare_template(target=base, max_size=size, *args, **kwargs)

            # NOTE(mikal): Update the mtime of the base file so the image
            # cache manager knows it is in use.
            libvirt_utils.update_mtime(base)
            self.verify_base_size(base, size)
            if not os.path.exists(self.path):
                with fileutils.remove_path_on_error(self.path):
                    copy_raw_image(base, self.path, size)

        self.correct_format()