'Open a file for writing the image file for an image
with supplied identifier.
:param image_id: Image ID'

@contextmanager
def open_for_write(self, image_id):

    incomplete_path = self.get_image_filepath(image_id, 'incomplete')
    def set_attr(key, value):
        set_xattr(incomplete_path, key, value)
    def commit():
        set_attr('hits', 0)
        final_path = self.get_image_filepath(image_id)
        LOG.debug("Fetch    finished,    moving    '%(incomplete_path)s'    to    '%(final_path)s'", dict(incomplete_path=incomplete_path, final_path=final_path))
        os.rename(incomplete_path, final_path)
        if self.is_queued(image_id):
            LOG.debug("Removing    image    '%s'    from    queue    after    caching    it.", image_id)
            fileutils.delete_if_exists(self.get_image_filepath(image_id, 'queue'))
    def rollback(e):
        set_attr('error', encodeutils.exception_to_unicode(e))
        invalid_path = self.get_image_filepath(image_id, 'invalid')
        LOG.debug("Fetch    of    cache    file    failed    (%(e)s),    rolling    back    by    moving    '%(incomplete_path)s'    to    '%(invalid_path)s'", {'e': encodeutils.exception_to_unicode(e), 'incomplete_path': incomplete_path, 'invalid_path': invalid_path})
        os.rename(incomplete_path, invalid_path)
    try:
        with open(incomplete_path, 'wb') as cache_file:
            (yield cache_file)
    except Exception as e:
        with excutils.save_and_reraise_exception():
            rollback(e)
    else:
        commit()
    finally:
        if os.path.exists(incomplete_path):
            rollback('incomplete    fetch')
