def testUpdateMapsTrapsPermissionDenied(self): self.mox.StubOutWithMock(map_updater.MapUpdater, 'UpdateFromSource') map_updater.MapUpdater.UpdateFromSource(mox.IgnoreArg(), incremental=True, force_write=False).AndRaise( error.PermissionDenied) self.mox.StubOutClassWithMocks(lock, 'PidFile') lock_mock = lock.PidFile(filename=None) lock_mock.Lock(force=False).AndReturn(True) lock_mock.Locked().AndReturn(True) lock_mock.Unlock() self.conf.maps = [config.MAP_PASSWORD] self.conf.cache = 'dummy' modify_stamp = 1 map_entry = passwd.PasswdMapEntry({'name': 'foo', 'uid': 10, 'gid': 10}) passwd_map = passwd.PasswdMap([map_entry]) passwd_map.SetModifyTimestamp(modify_stamp) source_mock = self.mox.CreateMock(source.Source) self.mox.StubOutWithMock(source_factory, 'Create') source_factory.Create(self.conf.options[ config.MAP_PASSWORD].source).AndReturn(source_mock) cache_mock = self.mox.CreateMock(caches.Cache) self.mox.StubOutWithMock(cache_factory, 'Create') self.mox.ReplayAll() c = command.Update() self.assertEqual( 1, c.UpdateMaps(self.conf, incremental=True, force_write=False))
def testUpdateSingleMaps(self): self.mox.StubOutClassWithMocks(lock, 'PidFile') lock_mock = lock.PidFile(filename=None) lock_mock.Lock(force=False).AndReturn(True) lock_mock.Locked().AndReturn(True) lock_mock.Unlock() self.conf.maps = [config.MAP_PASSWORD] self.conf.cache = 'dummy' modify_stamp = 1 map_entry = passwd.PasswdMapEntry({'name': 'foo', 'uid': 10, 'gid': 10}) passwd_map = passwd.PasswdMap([map_entry]) passwd_map.SetModifyTimestamp(modify_stamp) source_mock = self.mox.CreateMock(source.Source) source_mock.GetMap(config.MAP_PASSWORD, location=None).AndReturn(passwd_map) self.mox.StubOutWithMock(source_factory, 'Create') source_factory.Create(self.conf.options[ config.MAP_PASSWORD].source).AndReturn(source_mock) cache_mock = self.mox.CreateMock(caches.Cache) cache_mock.WriteMap(map_data=passwd_map).AndReturn(0) self.mox.StubOutWithMock(cache_factory, 'Create') cache_factory.Create(self.conf.options[config.MAP_PASSWORD].cache, config.MAP_PASSWORD).AndReturn(cache_mock) self.mox.ReplayAll() c = command.Update() self.assertEqual( 0, c.UpdateMaps(self.conf, incremental=True, force_write=False))
def testVerifySourcesGood(self): source_mock = self.mox.CreateMock(source.Source) source_mock.Verify().AndReturn(0) self.mox.StubOutWithMock(source_factory, 'Create') source_factory.Create(mox.IgnoreArg()).AndReturn(source_mock) self.conf.maps = [config.MAP_PASSWORD] self.mox.ReplayAll() self.assertEquals(0, command.Verify().VerifySources(self.conf))
def testCreate(self): class DummySource(source.Source): name = 'dummy' source_factory.RegisterImplementation(DummySource) dummy_config = {'name': 'dummy'} dummy_source = source_factory.Create(dummy_config) self.assertEqual(DummySource, type(dummy_source))
def testVerifySourcesBad(self): self.conf.maps = [] self.assertEquals(1, command.Verify().VerifySources(self.conf)) source_mock = self.mox.CreateMock(source.Source) source_mock.Verify().AndReturn(1) self.mox.StubOutWithMock(source_factory, 'Create') source_factory.Create(self.conf.options[ config.MAP_PASSWORD].cache).AndReturn(source_mock) self.conf.maps = [config.MAP_PASSWORD] self.mox.ReplayAll() self.assertEquals(1, command.Verify().VerifySources(self.conf))
def testUpdateAutomounts(self): self.mox.StubOutClassWithMocks(lock, 'PidFile') lock_mock = lock.PidFile(filename=None) lock_mock.Lock(force=False).AndReturn(True) lock_mock.Locked().AndReturn(True) lock_mock.Unlock() self.conf.maps = [config.MAP_AUTOMOUNT] self.conf.cache = 'dummy' modify_stamp = 1 map_entry = automount.AutomountMapEntry() map_entry.key = '/home' map_entry.location = 'foo' automount_map = automount.AutomountMap([map_entry]) automount_map.SetModifyTimestamp(modify_stamp) source_mock = self.mox.CreateMock(source.Source) source_mock.GetAutomountMasterMap().AndReturn(automount_map) source_mock.GetMap(config.MAP_AUTOMOUNT, location='foo').AndReturn(automount_map) self.mox.StubOutWithMock(source_factory, 'Create') source_factory.Create(self.conf.options[ config.MAP_PASSWORD].source).AndReturn(source_mock) cache_mock = self.mox.CreateMock(caches.Cache) cache_mock.GetMapLocation().AndReturn('home') cache_mock.WriteMap(map_data=automount_map).AndReturn(0) cache_mock.WriteMap(map_data=automount_map).AndReturn(0) self.mox.StubOutWithMock(cache_factory, 'Create') cache_factory.Create( self.conf.options[config.MAP_AUTOMOUNT].cache, config.MAP_AUTOMOUNT, automount_mountpoint='/home').AndReturn(cache_mock) cache_factory.Create(self.conf.options[config.MAP_AUTOMOUNT].cache, config.MAP_AUTOMOUNT, automount_mountpoint=None).AndReturn(cache_mock) self.mox.ReplayAll() c = command.Update() self.assertEquals( 0, c.UpdateMaps(self.conf, incremental=True, force_write=False))
def VerifySources(self, conf): """Verify each possible source and return the appropriate retval.""" possible_sources = set() retval = 0 for map_name in conf.maps: possible_sources.add(map_name) if possible_sources: for map_name in possible_sources: source_options = conf.options[map_name].source try: source = source_factory.Create(source_options) except error.SourceUnavailable, e: self.log.debug('map %s dumps source error %s', map_name, e) self.log.error('Map %s is unvavailable!', map_name) retval +=1 continue retval += source.Verify()
def UpdateMaps(self, conf, incremental, force_write=False, force_lock=False): """Update each configured map. For each configured map, create a source and cache object and update the cache from the source. Args: conf: configuration object incremental: flag indicating incremental update should occur force_write: optional flag indicating safety checks should be ignored force_lock: optional flag indicating we override existing locks Returns: integer, zero indicating success, non-zero failure """ # Grab a lock before we continue! if not self._Lock(path=conf.lockfile, force=force_lock): self.log.error('Failed to acquire lock, aborting!') return self.ERR_LOCK retval = 0 for map_name in conf.maps: if map_name not in conf.options: self.log.error('No such map name defined in config: %s', map_name) return 1 if incremental: self.log.info('Updating and verifying %s cache.', map_name) else: self.log.info('Rebuilding and verifying %s cache.', map_name) cache_options = conf.options[map_name].cache source_options = conf.options[map_name].source # Change into the target directory. # Sources such as zsync handle their temporary files badly, so we # want to be in the same location that the destination file will # exist in, so that the atomic rename occurs in the same # filesystem. # In addition, we create a tempdir below this dir to work in, because # zsync's librcksum sometimes leaves temp files around, and we don't # want to leave file turds around /etc. # We save and restore the directory here as each cache can define its own # output directory. # Finally, relative paths in the config are treated as relative to the # startup directory, but we convewrt them to absolute paths so that future # temp dirs do not mess with our output routines. old_cwd = os.getcwd() tempdir = tempfile.mkdtemp(dir=cache_options['dir'], prefix='nsscache-%s-' % map_name) if not os.path.isabs(cache_options['dir']): cache_options['dir'] = os.path.abspath(cache_options['dir']) if not os.path.isabs(conf.timestamp_dir): conf.timestamp_dir = os.path.abspath(conf.timestamp_dir) if not os.path.isabs(tempdir): tempdir = os.path.abspath(tempdir) os.chdir(tempdir) # End chdir dirty hack. try: try: source = source_factory.Create(source_options) updater = self._Updater(map_name, source, cache_options, conf) if incremental: self.log.info('Updating and verifying %s cache.', map_name) else: self.log.info('Rebuilding and verifying %s cache.', map_name) retval = updater.UpdateFromSource(source, incremental=incremental, force_write=force_write) except error.PermissionDenied: self.log.error('Permission denied: could not update map %r. Aborting', map_name) retval += 1 except (error.EmptyMap, error.InvalidMap), e: self.log.error(e) retval += 1 except error.InvalidMerge, e: self.log.warn('Could not merge map %r: %s. Skipping.', map_name, e)