Project

General

Profile

Bug #10711

Updated by Janos Mattyasovszky almost 7 years ago

Version: @4.1.2.rc1.git201705040133@ on @CFEngine Core 3.10.0@ 

 In @./inventory/1.0/fusionAgent.cf@ there is: 

 <pre> 
     # guarding execresult to save a lot of time during policy validation 
     !windows.(force_inventory|inventory_time):: 
       "fusion_inventory_version" string => execresult("${g.rudder_base}/bin/run-inventory --version | ${paths.path[grep]} '[0-9]\.[0-9]' | 
  ${paths.path[sed]} 's%.*(\([0-9]\+\)\.\([0-9]\+\).*).*%\1\2%'", "useshell"); 
       "inventory_path"             string => "${g.rudder_var_tmp}/inventory", policy => "overridable"; # Default value 
       "inventory_path_edition"     string => "${g.rudder_var_tmp}/inventory/.*.ocs", policy => "overridable"; # Default value for editing th 
 e inventory files 
 </pre> 

 =>    the execution of "execresult" is guarded 
 => it will only be executed if "@!windows.(force_inventory|inventory_time)@", and only then is "@inventory_path@" defined. 

 However, the actual inventory run does not follow this conditions, it is enough for the inventory directory to just be created, it does not depend on the variable of @inventory_path@ actually being set: 

 <pre> 
   commands: 
     !windows.inventoryfoldercreated:: 
       "${g.rudder_base}/bin/run-inventory --local=${inventory_path}" 
         classes => cf2_if_else("run_inventory", "inventory_failed"), 
         comment => "Generating inventory, in the temporary folder"; 
 </pre> 

 This results in a File of @${inventory_path}@ being created in the @/@ if the directory was just created: 

 <pre> 
 rudder41n:~ # rmdir /var/rudder/tmp/inventory/ 
 rudder41n:~ # rudder agent run -q 
 Rudder agent 4.1.2.rc1.git201705040133 (CFEngine Core 3.10.0) 
 Node uuid: root 
 #Start execution with config [20170505-095043-72de9bee] 

 M| State           Technique                   Component                   Key                  Message 
 E| error           Inventory                   inventory                                      #Generated inventory has been detected as invalid 

 ## Summary ##################################################################### 
 32 components verified in 4 directives 
    => 32 components in Enforce mode 
       -> 29 compliant 
       -> 2 not-applicable 
       -> 1 error 
 execution time: 6.47s 
 ################################################################################ 
 rudder41n:~ # 

 rudder41n:~ # ll /\$\{inventory_path\} 
 -rw------- 1 root root 324182 May    5 12:31 /${inventory_path} 
 rudder41n:~ # 
 </pre> 



 The very strange for this is, that the check should only run if the @inventory_file_exist@ class is set, which is defined by using @filesexist@ based on a @findfiles@, but that somehow returns true, even if you try to search a bunch of files "*.ocs" in an empty folder by using an intermediate array: 

 See child ticket #10712 for detailed description. @rudder agent run -d@ proper part: 
 <pre> 
 rudder      debug: Evaluating function: findfiles("${g.rudder_var_tmp}/inventory/*.ocs") 
 rudder      debug: Evaluating vars promise: inventory_file 
 rudder      debug: DeRefCopyPromise(): promiser:'perl_command' 
 rudder      debug: DeRefCopyPromise():       copying constraint: 'string' 
 rudder      debug: Evaluating vars promise: perl_command 
 rudder    verbose: V: ......................................................... 
 rudder    verbose: V: BEGIN variables (pass 1) 
 rudder      debug: DeRefCopyPromise(): promiser:'inventory_file' 
 rudder      debug: DeRefCopyPromise():       copying constraint: 'slist' 
 rudder      debug: Evaluating function: findfiles("${g.rudder_var_tmp}/inventory/*.ocs") 
 rudder    verbose: V:       Computing value of 'inventory_file' 
 rudder      debug: Evaluating vars promise: inventory_file 
 rudder      debug: V: 'inventory_file' => '' 
 rudder      debug: Evaluating vars promise: inventory_file 
 rudder      debug: DeRefCopyPromise(): promiser:'perl_command' 
 rudder      debug: DeRefCopyPromise():       copying constraint: 'string' 
 rudder    verbose: V:       Computing value of 'perl_command' 
 rudder      debug: Evaluating vars promise: perl_command 
 rudder      debug: V: 'perl_command' => '/usr/bin/perl' 
 rudder      debug: Evaluating vars promise: perl_command 
 rudder    verbose: C: ......................................................... 
 rudder    verbose: C: BEGIN classes / conditions (pass 1) 
 rudder      debug: DeRefCopyPromise(): promiser:'inventory_file_exist' 
 rudder      debug: DeRefCopyPromise():       copying constraint: 'expression' 
 rudder      debug: Evaluating function: filesexist("@{inventory_file}") 
 rudder      debug: Evaluating classes promise: inventory_file_exist 
 rudder    verbose: C:       +    Private class: inventory_file_exist 
 rudder      debug: Setting class: default:inventory_file_exist 
 </pre> 

 But: 
 <pre> 
 # ll /var/rudder/tmp/inventory 
 total 0 
 </pre> 

 Here is an example code what I have copy-pasted together to demonstrate the behavior: 

 Run @mkdir /tmp/empty@ before :-) 

 test.cf: 
 <pre> 
 body common control 
 { 
       bundlesequence    => { "example" }; 
 } 

 bundle agent example 
 { 

   vars: 
       "tmpdir" string => "/tmp/empty"; 
       "mylist" slist    => findfiles("${tmpdir}/*.ocs"); 

   classes: 
       "exists" expression => filesexist("@{mylist}"); 

   reports: 
       "My list: @{mylist}"; 

     exists:: 
       "Case exist!"; 
     !exists:: 
       "Case does not exist!"; 

 } 
 </pre> 

 Output is basically a "true" class even if the files don't exist! 

 <pre> 
 # cf-agent -f ./test.cf 
 R: My list: @{mylist} 
 R: Case exist! 
 </pre>

Back