Document type stdin inside loop caveats
This commit is contained in:
		
					parent
					
						
							
								520cfeda98
							
						
					
				
			
			
				commit
				
					
						68837e45cc
					
				
			
		
					 2 changed files with 68 additions and 0 deletions
				
			
		| 
						 | 
					@ -4,6 +4,7 @@ Changelog
 | 
				
			||||||
next:
 | 
					next:
 | 
				
			||||||
	* Type __apt_key: Use gpg key, fallback to deprecated apt-key (Ander Punnar)
 | 
						* Type __apt_key: Use gpg key, fallback to deprecated apt-key (Ander Punnar)
 | 
				
			||||||
	* Type __acl: Fix and improve (Ander Punnar)
 | 
						* Type __acl: Fix and improve (Ander Punnar)
 | 
				
			||||||
 | 
						* Documentation: Document type stdin inside loop caveats (Darko Poljak)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
5.1.0: 2019-05-22
 | 
					5.1.0: 2019-05-22
 | 
				
			||||||
	* Type __consul: Add alpine support (Nico Schottelius)
 | 
						* Type __consul: Add alpine support (Nico Schottelius)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -216,6 +216,73 @@ In the __file type, stdin is used as source for the file, if - is used for sourc
 | 
				
			||||||
    ....
 | 
					    ....
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Stdin inside a loop
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					Since cdist saves type's stdin content in the object as **$__object/stdin**,
 | 
				
			||||||
 | 
					so it can be accessed in manifest and gencode-* scripts, this can lead to
 | 
				
			||||||
 | 
					unexpected behavior. For example, suppose you have some type with the following
 | 
				
			||||||
 | 
					in its manifest:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if [ -f "$__object/parameter/foo" ]
 | 
				
			||||||
 | 
					    then
 | 
				
			||||||
 | 
					        while read -r l
 | 
				
			||||||
 | 
					        do
 | 
				
			||||||
 | 
					            __file "$l"
 | 
				
			||||||
 | 
					            echo "$l" >&2
 | 
				
			||||||
 | 
					        done < "$__object/parameter/foo"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					and init manifest:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __foo foo --foo a --foo b --foo c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You expect that manifest stderr content is:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a
 | 
				
			||||||
 | 
					    b
 | 
				
			||||||
 | 
					    c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					and that files *a*, *b* and *c* are created. But all you get in manifest stderr
 | 
				
			||||||
 | 
					is:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					and only *a* file is created.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When redirecting parameter *foo* file content to while's stdin that means that all
 | 
				
			||||||
 | 
					commands in while body have this same stdin. So when *__file* type gets executed,
 | 
				
			||||||
 | 
					cdist saves its stdin which means it gets the remaining content of parameter *foo*
 | 
				
			||||||
 | 
					file, i.e.:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    b
 | 
				
			||||||
 | 
					    c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The solution is to make sure that your types inside such loops get their stdin
 | 
				
			||||||
 | 
					from somewhere else, e.g. for the above problem *__file* type can get empty
 | 
				
			||||||
 | 
					stdin from */dev/null*:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if [ -f "$__object/parameter/foo" ]
 | 
				
			||||||
 | 
					    then
 | 
				
			||||||
 | 
					        while read -r l
 | 
				
			||||||
 | 
					        do
 | 
				
			||||||
 | 
					            __file "$l" < /dev/null
 | 
				
			||||||
 | 
					            echo "$l" >&2
 | 
				
			||||||
 | 
					        done < "$__object/parameter/foo"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Writing the manifest
 | 
					Writing the manifest
 | 
				
			||||||
--------------------
 | 
					--------------------
 | 
				
			||||||
In the manifest of a type you can use other types, so your type extends
 | 
					In the manifest of a type you can use other types, so your type extends
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue