Changeset 467

Show
Ignore:
Timestamp:
05/19/08 13:04:33 (8 months ago)
Author:
jmowery
Message:

incremental check-in of new storage: lock, unlock, rollback, and update

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/trunk-pmd-intproto/server/storage.py

    r466 r467  
    285285        def update(self): 
    286286                '''Update all fields and sync to disk. This function should be called regularly and whenever the object will go out of scope.''' 
    287                 raise NotImplementedError 
     287                if not self.storage: 
     288                        if not is_controlled(self.name): 
     289                                return 
     290                        else: 
     291                                self.__init__(self.name) 
     292                                return #. was placed under control recently re-init and return 
     293                self.config.set('general', 'description', self.description) 
     294                self.storage.root = find_control_root(self.storage.path) 
     295                self.config.set('general', 'root', self.storage.root) 
     296                local_status_date = int(os.stat(self.storage.status_path)[stat.ST_MTIME]) 
     297                if self.storage.time < local_status_date: #on disk data changed since last access 
     298                        raise FutureWarning, 'Merging of concurrent updates is not currently supported.' 
     299                if not self.modified: 
     300                        return #no merges, no local changes 
     301                now = int(time.time()) 
     302                layer_latest = 0 
     303                for name in self.list_controlled_files(): #update all latest fields 
     304                        file_latest = self.storage.find_recent(name, now) 
     305                        if file_latest != self.entries[name].latest: 
     306                                self.entries[name].latest = file_latest 
     307                                self.modified = True 
     308                        if file_latest > layer_latest: 
     309                                layer_latest = file_latest 
     310                if layer_latest: #will be 0 if layer is empty 
     311                        if layer_latest != self.entries['.'].latest: 
     312                                self.entries['.'].latest = layer_latest 
     313                                self.modified = True 
     314                if self.entries['.'].applied > self.entries['.'].latest: 
     315                        self.entries['.'].applied = self.entries['.'].latest #can't be applied newer than latest entry 
     316                        self.modified = True 
     317                for name in self.list_controlled_files(): #update all applied fields 
     318                        file_current = self.storage.find_recent(name, self.entries[name].applied) 
     319                        if file_current != self.entries[name].applied: 
     320                                self.entries[name].applied = file_current 
     321                                self.modified = True 
     322                                if self.is_locked(name): 
     323                                        file_name = os.path.join(self.storage.path, name) 
     324                                        cur_file = self.get_current(name) 
     325                                        if os.path.lexists(file_name): 
     326                                                os.remove(file_name) 
     327                                        if cur_file: #i.e. if there is a valid version at this applied time 
     328                                                os.symlink(cur_file, file_name) 
     329                if self.modified: 
     330                        self.write() #sync to disk, clear modified, and update access time for status file 
    288331 
    289332        def write(self): 
     
    303346                if date is None: 
    304347                        date = int(time.time()) 
    305                 raise NotImplementedError 
     348                else: 
     349                        date = int(date) 
     350                if not self.storage: 
     351                        return 
     352                if not self.entries.has_key(name): 
     353                        raise ValueError, 'Layer \'' + self.name + '\' has no entry for \'' + name + '\'.' 
     354                if name == '.': 
     355                        self.entries['.'].applied = date 
     356                        for n in list_controlled_files(): 
     357                                self.entries[n].applied = date 
     358                        self.modified = True 
     359                        self.update() 
     360                        if recursive: 
     361                                for d in self.list_controlled_dirs(): 
     362                                        l = Layer(os.path.join(self.storage.path, d)) 
     363                                        l.rollback(date, '.', recursive) 
     364                                        l.update() 
     365                elif self.entries[name].type == 'DIR' or self.entries[name].type == 'LOCAL': 
     366                        l = Layer(os.path.join(self.storage.path, name)) 
     367                        l.rollback(date, '.', recursive) 
     368                        l.update() 
     369                else: 
     370                        self.entries[name].applied = date 
     371                        self.update() 
    306372 
    307373        def export(self, dest_path): 
     
    452518                self.storage.config.set('general', 'root', self.storage.root) 
    453519                self.storage.config.add_section('entries') 
    454                 self.storage.add_dir('.') 
     520                self.entries['.'] = self.storage.add_dir('.') 
    455521                self.storage.write() 
    456522                if is_controlled(os.path.join(self.storage.path, '..')): 
     
    640706                if not self.stprage: 
    641707                        raise RuntimeError, 'Attempt to lock files in uncontroled layer.' 
    642                 raise NotImplementedError 
     708                if names.__class__ == [].__class__: 
     709                        for name in names: 
     710                                self.lock(name, recursive) 
     711                name = os.path.basename(name) 
     712                if not self.entries.has_key(name): 
     713                        raise ValueError, 'Layer \'' + self.name + '\' has no entry for \'' + name +'\'.' 
     714                if self.is_locked(name) and not recursive: 
     715                        return 
     716                if name == '.': 
     717                        self.modified = True 
     718                        if recursive: 
     719                                for n in self.list_controlled(): 
     720                                        self.lock(n, recursive) 
     721                        self.entries['.'].lock = True #lock other files before . 
     722                elif self.entries[name].type == 'DIR' or self.entries[name].type == 'LOCAL': 
     723                        l = Layer(os.path.join(self.storage.path, name)) 
     724                        l.lock('.', recursive) 
     725                        l.update 
     726                else: 
     727                        if self.is_locked(): 
     728                                raise RuntimeError, 'Layer \'' + self.name + '\' is locked; cannot modify status of \'' + name + '\'' 
     729                        self.modified = True 
     730                        if self.is_modified(name): 
     731                                self.add(name) 
     732                        self.entries[name].lock = True 
     733                        link_target = self.get_current(name) 
     734                        os.remove(os.path.join(self.storage.path, name)) 
     735                        if link_target: #if current version is 0 (disabled) link_target will be '' and no link should exist 
     736                                os.symlink(link_target, os.path.join(self.storage.path, name)) 
    643737 
    644738        def unlock(self, names=['.'], recursive=False): 
    645739                '''Unlock each file or directory in names.''' 
    646                 raise NotImplementedError 
     740                if not self.stprage: 
     741                        raise RuntimeError, 'Attempt to lock files in uncontroled layer.' 
     742                if names.__class__ == [].__class__: 
     743                        for name in names: 
     744                                self.unlock(name, recursive) 
     745                name = os.path.basename(name) 
     746                if not self.entries.has_key(name): 
     747                        raise ValueError, 'Layer \'' + self.name + '\' has no entry for \'' + name +'\'.' 
     748                if not self.is_locked(name) and not recursive: 
     749                        return 
     750                if name == '.': 
     751                        self.modified = True 
     752                        self.entries['.'].lock = False #unlock . before other files 
     753                        if recursive: 
     754                                for n in self.list_controlled(): 
     755                                        self.unlock(n, recursive) 
     756                elif self.entries[name].type == 'DIR' or self.entries[name].type == 'LOCAL': 
     757                        l = Layer(os.path.join(self.storage.path, name)) 
     758                        l.unlock('.', recursive) 
     759                        l.update 
     760                else: 
     761                        if self.is_locked(): 
     762                                raise RuntimeError, 'Layer \'' + self.name + '\' is locked; cannot modify status of \'' + name + '\'' 
     763                        self.modified = True 
     764                        file_name = os.path.join(self.storage.path, name) 
     765                        if os.path.lexists(file_name): 
     766                                link_target = os.readlink(file_name) 
     767                        else: 
     768                                link_target = '' 
     769                        os.remove(file_name) 
     770                        if link_target: #if current version is 0 (disabled) link_target will be '' and no link should exist 
     771                                shutil.copy2(link_target, file_name) 
     772                                os.chmod(file_name, os.stat(file_name)[stat.ST_MODE]|stat.S_IWUSR) 
     773                        self.entries[name].lock = False 
    647774 
    648775        def is_locked(self, name='.', recursive=False): #add recursive as option)