This file is indexed.

/usr/lib/python2.7/dist-packages/glare/locking.py is in python-glare 0.4.1-3ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Copyright 2016 OpenStack Foundation
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
from oslo_log import log as logging

LOG = logging.getLogger(__name__)


class LockApiBase(object):
    """Lock Api Base class that responsible for acquiring/releasing locks."""

    def create_lock(self, context, lock_key):
        """Acquire lock for current user.

        :param context: user context
        :param lock_key: unique lock identifier that defines lock scope
        :return: lock internal identifier
        """
        raise NotImplementedError()

    def delete_lock(self, context, lock_id):
        """Delete acquired user lock.

        :param context: user context
        :param lock_id: lock internal identifier
        """
        raise NotImplementedError()


class Lock(object):
    """Object that stores lock context for users. This class is internal
    and used only in lock engine, so users shouldn't use this class directly.
    """

    def __init__(self, context, lock_id, lock_key, release_method):
        """Initialize lock context."""
        self.context = context
        self.lock_id = lock_id
        self.lock_key = lock_key
        self.release = release_method

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # TODO(kairat) catch all exceptions here
        self.release(self)


class LockEngine(object):
    """Glare lock engine.

    Defines how artifact updates must be synchronized with each other. When
    some user obtains a lock for the same artifact then other user cannot
    request that lock and gets a Conflict error.
    """
    # NOTE(kairat): Lock Engine also allows to encapsulate lock logic in one
    # place so we can potentially add tooz functionality in future to Glare.
    # Right now there are troubles with locks in Galera (especially in mysql)
    # and zookeeper requires additional work from IT engineers. So we need
    # support production ready DB locks in our implementation.

    MAX_LOCK_LENGTH = 255

    def __init__(self, lock_api):
        """Initialize lock engine with some lock api.

        :param lock_api: api that allows to create/delete locks
        """
        # NOTE(kairat): lock_api is db_api now but it might be
        # replaced with DLM in near future.
        self.lock_api = lock_api

    def acquire(self, context, lock_key):
        """Acquire lock for artifact.

        If there is some other lock with the same key then
        raise Conflict Error.

        :param context: user context
        :param lock_key: lock key
        :return: lock definition
        """
        if lock_key is not None and len(lock_key) < self.MAX_LOCK_LENGTH:
            lock_id = self.lock_api.create_lock(context, lock_key)
            LOG.debug("Lock %(lock_id)s acquired for lock_key %(lock_key)s",
                      {'lock_id': lock_id, 'lock_key': lock_key})
        else:
            lock_id = None
            LOG.debug("No lock for lock_key %s", lock_key)

        return Lock(context, lock_id, lock_key, self.release)

    def release(self, lock):
        """Release lock for artifact.

        :param lock: Lock object
        """
        if lock.lock_id is not None:
            self.lock_api.delete_lock(lock.context, lock.lock_id)
            LOG.debug("Lock %(lock_id)s released for lock_key %(key)s",
                      {'lock_id': lock.lock_id, 'key': lock.lock_key})