imip-agent

imiptools/filesys.py

356:adf8e079e7c5
2015-02-27 Paul Boddie Actually set directory permissions: makedirs seems not to bother doing so. recurring-events
     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 def make_path(base, parts):    38     for part in parts:    39         pathname = join(base, part)    40         if not exists(pathname):    41             mkdir(pathname)    42             fix_permissions(pathname, True)    43         base = pathname    44     45 class FileBase:    46     47     "Basic filesystem operations."    48     49     lock_name = "__lock__"    50     51     def __init__(self, store_dir):    52         self.store_dir = store_dir    53         if not exists(self.store_dir):    54             makedirs(self.store_dir)    55             fix_permissions(self.store_dir, True)    56     57     def get_file_object(self, base, *parts):    58         pathname = join(base, *parts)    59         return check_dir(base, pathname) and pathname or None    60     61     def get_object_in_store(self, *parts):    62     63         """    64         Return the name of any valid object stored within a hierarchy specified    65         by the given 'parts'.    66         """    67     68         parent = expected = self.store_dir    69     70         for part in parts:    71             filename = self.get_file_object(expected, part)    72             if not filename:    73                 return False    74             parent = expected    75             expected = filename    76     77         if not exists(parent):    78             make_path(self.store_dir, parts[:-1])    79     80         return filename    81     82     # Locking methods.    83     # This uses the directory creation method exploited by MoinMoin.util.lock.    84     # However, a simple single lock type mechanism is employed here.    85     86     def get_lock_dir(self, *parts):    87         parts = parts and list(parts) or []    88         parts.append(self.lock_name)    89         return self.get_object_in_store(*parts)    90     91     def acquire_lock(self, timeout=None, *parts):    92     93         """    94         Acquire an exclusive lock on the directory or a path within it described    95         by 'parts'.    96         """    97     98         start = now = time()    99    100         while not timeout or now - start < timeout:   101             try:   102                 mkdir(self.get_lock_dir(*parts))   103                 break   104             except OSError, exc:   105                 if exc.errno != errno.EEXIST:   106                     raise   107             sleep(1)   108             now = time()   109    110     def release_lock(self, *parts):   111    112         """   113         Release an acquired lock on the directory or a path within it described   114         by 'parts'.   115         """   116    117         try:   118             rmdir(self.get_lock_dir(*parts))   119         except OSError, exc:   120             if exc.errno != errno.ENOENT:   121                 raise   122    123 # vim: tabstop=4 expandtab shiftwidth=4