Add warning message for faulty dependencies case.
This commit is contained in:
		
					parent
					
						
							
								88b436b4c1
							
						
					
				
			
			
				commit
				
					
						d49af95d3c
					
				
			
		
					 18 changed files with 138 additions and 3 deletions
				
			
		|  | @ -1,5 +1,5 @@ | |||
| cdist-type__firewalld_start(7) | ||||
| ============================= | ||||
| ============================== | ||||
| 
 | ||||
| NAME | ||||
| ---- | ||||
|  |  | |||
|  | @ -84,6 +84,10 @@ class Emulator(object): | |||
|         self.type_name = os.path.basename(argv[0]) | ||||
|         self.cdist_type = core.CdistType(self.type_base_path, self.type_name) | ||||
| 
 | ||||
|         # If set then object alreay exists and this var holds existing | ||||
|         # requirements. | ||||
|         self._existing_reqs = None | ||||
| 
 | ||||
|         self.__init_log() | ||||
| 
 | ||||
|     def run(self): | ||||
|  | @ -166,6 +170,9 @@ class Emulator(object): | |||
|                 self.parameters[key] = value | ||||
| 
 | ||||
|         if self.cdist_object.exists and 'CDIST_OVERRIDE' not in self.env: | ||||
|             # Make existing requirements a set so that we can compare it | ||||
|             # later with new requirements. | ||||
|             self._existing_reqs = set(self.cdist_object.requirements) | ||||
|             if self.cdist_object.parameters != self.parameters: | ||||
|                 errmsg = ("Object %s already exists with conflicting " | ||||
|                           "parameters:\n%s: %s\n%s: %s" % ( | ||||
|  | @ -243,7 +250,7 @@ class Emulator(object): | |||
|         return cdist_object.name | ||||
| 
 | ||||
|     def record_requirements(self): | ||||
|         """record requirements""" | ||||
|         """Record requirements.""" | ||||
| 
 | ||||
|         # Inject the predecessor, but not if its an override | ||||
|         # (this would leed to an circular dependency) | ||||
|  | @ -267,6 +274,7 @@ class Emulator(object): | |||
|                     # so do not set a requirement | ||||
|                     pass | ||||
| 
 | ||||
|         reqs = set() | ||||
|         if "require" in self.env: | ||||
|             requirements = self.env['require'] | ||||
|             self.log.debug("reqs = " + requirements) | ||||
|  | @ -274,7 +282,23 @@ class Emulator(object): | |||
|                 # Ignore empty fields - probably the only field anyway | ||||
|                 if len(requirement) == 0: | ||||
|                     continue | ||||
|                 self.record_requirement(requirement) | ||||
|                 object_name = self.record_requirement(requirement) | ||||
|                 reqs.add(object_name) | ||||
|         if self._existing_reqs is not None: | ||||
|             # If object exists then compare existing and new requirements. | ||||
|             if self._existing_reqs != reqs: | ||||
|                 warnmsg = ("Object {} already exists with requirements:\n" | ||||
|                            "{}: {}\n" | ||||
|                            "{}: {}\n" | ||||
|                            "Dependency resolver could not handle dependencies " | ||||
|                            "as expected.".format( | ||||
|                                self.cdist_object.name, | ||||
|                                " ".join(self.cdist_object.source), | ||||
|                                self._existing_reqs, | ||||
|                                self.object_source, | ||||
|                                reqs | ||||
|                            )) | ||||
|                 self.log.warning(warnmsg) | ||||
| 
 | ||||
|     def record_auto_requirements(self): | ||||
|         """An object shall automatically depend on all objects that it | ||||
|  |  | |||
|  | @ -177,6 +177,22 @@ class ConfigRunTestCase(test.CdistTestCase): | |||
|         dryrun.run() | ||||
|         # if we are here, dryrun works like expected | ||||
| 
 | ||||
|     def test_desp_resolver(self): | ||||
|         """Test to show dependency resolver warning message.""" | ||||
|         local = cdist.exec.local.Local( | ||||
|             target_host=self.target_host, | ||||
|             base_root_path=self.host_base_path, | ||||
|             host_dir_name=self.hostdir, | ||||
|             exec_path=os.path.abspath(os.path.join( | ||||
|                 my_dir, '../../../scripts/cdist')), | ||||
|             initial_manifest=os.path.join( | ||||
|                 fixtures, 'manifest/init-deps-resolver'), | ||||
|             add_conf_dirs=[fixtures]) | ||||
| 
 | ||||
|         # dry_run is ok for dependency testing | ||||
|         config = cdist.config.Config(local, self.remote, dry_run=True) | ||||
|         config.run() | ||||
| 
 | ||||
| 
 | ||||
| # Currently the resolving code will simply detect that this object does | ||||
| # not exist. It should probably check if the type is a singleton as well | ||||
|  |  | |||
							
								
								
									
										8
									
								
								cdist/test/config/fixtures/manifest/init-deps-resolver
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								cdist/test/config/fixtures/manifest/init-deps-resolver
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| __a a | ||||
| require="__e/e" __b b | ||||
| require="__f/f" __c c | ||||
| __e e | ||||
| __f f | ||||
| require="__c/c" __d d | ||||
| __g g | ||||
| __h h | ||||
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__a/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__a/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__b/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__b/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__c/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__c/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__d/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__d/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__e/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__e/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__f/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__f/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__g/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__g/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								cdist/test/config/fixtures/type/__g/manifest
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								cdist/test/config/fixtures/type/__g/manifest
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| require="__c/c __d/d" __a a | ||||
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__h/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__h/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								cdist/test/config/fixtures/type/__h/manifest
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								cdist/test/config/fixtures/type/__h/manifest
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| # require="__b/b" __a a | ||||
| require="__j/j" __i i | ||||
| __j j | ||||
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__i/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__i/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								cdist/test/config/fixtures/type/__j/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								cdist/test/config/fixtures/type/__j/.keep
									
										
									
									
									
										Normal file
									
								
							|  | @ -499,6 +499,60 @@ class StdinTestCase(test.CdistTestCase): | |||
|         self.assertEqual(random_string, stdin_saved_by_emulator) | ||||
| 
 | ||||
| 
 | ||||
| class EmulatorAlreadyExistingRequirementsWarnTestCase(test.CdistTestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         self.temp_dir = self.mkdtemp() | ||||
|         handle, self.script = self.mkstemp(dir=self.temp_dir) | ||||
|         os.close(handle) | ||||
|         base_path = self.temp_dir | ||||
|         hostdir = cdist.str_hash(self.target_host[0]) | ||||
|         host_base_path = os.path.join(base_path, hostdir) | ||||
| 
 | ||||
|         self.local = local.Local( | ||||
|             target_host=self.target_host, | ||||
|             base_root_path=host_base_path, | ||||
|             host_dir_name=hostdir, | ||||
|             exec_path=test.cdist_exec_path, | ||||
|             add_conf_dirs=[conf_dir]) | ||||
|         self.local.create_files_dirs() | ||||
| 
 | ||||
|         self.manifest = core.Manifest(self.target_host, self.local) | ||||
|         self.env = self.manifest.env_initial_manifest(self.script) | ||||
|         self.env['__cdist_object_marker'] = self.local.object_marker_name | ||||
| 
 | ||||
|     def tearDown(self): | ||||
|         shutil.rmtree(self.temp_dir) | ||||
| 
 | ||||
|     def test_object_existing_requirements_req_none(self): | ||||
|         """Test to show dependency resolver warning message.""" | ||||
|         argv = ['__directory', 'spam'] | ||||
|         emu = emulator.Emulator(argv, env=self.env) | ||||
|         emu.run() | ||||
|         argv = ['__file', 'eggs'] | ||||
|         self.env['require'] = '__directory/spam' | ||||
|         emu = emulator.Emulator(argv, env=self.env) | ||||
|         emu.run() | ||||
|         argv = ['__file', 'eggs'] | ||||
|         if 'require' in self.env: | ||||
|             del self.env['require'] | ||||
|         emu = emulator.Emulator(argv, env=self.env) | ||||
| 
 | ||||
|     def test_object_existing_requirements_none_req(self): | ||||
|         """Test to show dependency resolver warning message.""" | ||||
|         argv = ['__directory', 'spam'] | ||||
|         emu = emulator.Emulator(argv, env=self.env) | ||||
|         emu.run() | ||||
|         argv = ['__file', 'eggs'] | ||||
|         if 'require' in self.env: | ||||
|             del self.env['require'] | ||||
|         emu = emulator.Emulator(argv, env=self.env) | ||||
|         emu.run() | ||||
|         argv = ['__file', 'eggs'] | ||||
|         self.env['require'] = '__directory/spam' | ||||
|         emu = emulator.Emulator(argv, env=self.env) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     import unittest | ||||
|     unittest.main() | ||||
|  |  | |||
|  | @ -246,6 +246,35 @@ connection. In this case ssh will disable multiplexing. | |||
| This limit is controlled with sshd :strong:`MaxSessions` configuration | ||||
| options. For more details refer to :strong:`sshd_config`\ (5). | ||||
| 
 | ||||
| When requirements for the same object are defined in different manifests (see | ||||
| example below) in init manifest and in some other type manifest and they differs | ||||
| then dependency resolver cannot detect dependencies right. This happends because | ||||
| cdist cannot prepare all objects first and then run objects because some | ||||
| object can depend on the result of type explorer(s) and explorers are executed | ||||
| during object run. cdist will detect such case and write warning message. | ||||
| Example for such a case: | ||||
| 
 | ||||
| .. code-block:: sh | ||||
| 
 | ||||
|     init manifest: | ||||
|         __a a | ||||
|         require="__e/e" __b b | ||||
|         require="__f/f" __c c | ||||
|         __e e | ||||
|         __f f | ||||
|         require="__c/c" __d d | ||||
|         __g g | ||||
|         __h h | ||||
| 
 | ||||
|     type __g manifest: | ||||
|         require="__c/c __d/d" __a a | ||||
| 
 | ||||
|     Warning message: | ||||
|         .WARNING: cdisttesthost: Object __a/a already exists with requirements: | ||||
|         /usr/home/darko/ungleich/cdist/cdist/test/config/fixtures/manifest/init-deps-resolver /tmp/tmp.cdist.test.ozagkg54/local/759547ff4356de6e3d9e08522b0d0807/data/conf/type/__g/manifest: set() | ||||
|         /tmp/tmp.cdist.test.ozagkg54/local/759547ff4356de6e3d9e08522b0d0807/data/conf/type/__g/manifest: {'__c/c', '__d/d'} | ||||
|         Dependency resolver could not handle dependencies as expected. | ||||
| 
 | ||||
| COPYING | ||||
| ------- | ||||
| Copyright \(C) 2011-2013 Nico Schottelius. Free use of this software is | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue