imip-agent

imiptools/filesys.py

341:83cd574a7944
2015-02-12 Paul Boddie Apply the default directory permissions when using makedirs.
     1 #!/usr/bin/env python     2      3 """     4 Filesystem utilities.     5      6 Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>     7      8 This program is free software; you can redistribute it and/or modify it under     9 the terms of the GNU General Public License as published by the Free Software    10 Foundation; either version 3 of the License, or (at your option) any later    11 version.    12     13 This program is distributed in the hope that it will be useful, but WITHOUT    14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    15 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    16 details.    17     18 You should have received a copy of the GNU General Public License along with    19 this program.  If not, see <http://www.gnu.org/licenses/>.    20 """    21     22 import errno    23 from imiptools.config import DEFAULT_PERMISSIONS, DEFAULT_DIR_PERMISSIONS    24 from os.path import abspath, commonprefix, exists, join    25 from os import chmod, makedirs, mkdir, rmdir    26 from time import sleep, time    27     28 def check_dir(base, dir):    29     return commonprefix([base, abspath(dir)]) == base    30     31 def fix_permissions(filename, is_dir=False):    32     try:    33         chmod(filename, is_dir and DEFAULT_DIR_PERMISSIONS or DEFAULT_PERMISSIONS)    34     except OSError:    35         pass    36     37 class FileBase:    38     39     "Basic filesystem operations."    40     41     lock_name = "__lock__"    42     43     def __init__(self, store_dir):    44         self.store_dir = store_dir    45         if not exists(self.store_dir):    46             makedirs(self.store_dir, DEFAULT_DIR_PERMISSIONS)    47     48     def get_file_object(self, base, *parts):    49         pathname = join(base, *parts)    50         return check_dir(base, pathname) and pathname or None    51     52     def get_object_in_store(self, *parts):    53     54         """    55         Return the name of any valid object stored within a hierarchy specified    56         by the given 'parts'.    57         """    58     59         parent = expected = self.store_dir    60     61         for part in parts:    62             filename = self.get_file_object(expected, part)    63             if not filename:    64                 return False    65             parent = expected    66             expected = filename    67     68         if not exists(parent):    69             makedirs(parent, DEFAULT_DIR_PERMISSIONS)    70     71         return filename    72     73     # Locking methods.    74     # This uses the directory creation method exploited by MoinMoin.util.lock.    75     # However, a simple single lock type mechanism is employed here.    76     77     def get_lock_dir(self, *parts):    78         parts = parts and list(parts) or []    79         parts.append(self.lock_name)    80         return self.get_object_in_store(*parts)    81     82     def acquire_lock(self, timeout=None, *parts):    83     84         """    85         Acquire an exclusive lock on the directory or a path within it described    86         by 'parts'.    87         """    88     89         start = now = time()    90     91         while not timeout or now - start < timeout:    92             try:    93                 mkdir(self.get_lock_dir(*parts))    94                 break    95             except OSError, exc:    96                 if exc.errno != errno.EEXIST:    97                     raise    98             sleep(1)    99             now = time()   100    101     def release_lock(self, *parts):   102    103         """   104         Release an acquired lock on the directory or a path within it described   105         by 'parts'.   106         """   107    108         try:   109             rmdir(self.get_lock_dir(*parts))   110         except OSError, exc:   111             if exc.errno != errno.ENOENT:   112                 raise   113    114 # vim: tabstop=4 expandtab shiftwidth=4