The Puppet Labs Issue Tracker has Moved: https://tickets.puppetlabs.com

Bug #9996

2.7.5 and higher do not support multi-line strings in the 'command' portion of 'exec'.

Added by Trevor Vaughan about 3 years ago. Updated over 1 year ago.

Status:ClosedStart date:10/09/2011
Priority:HighDue date:
Assignee:Jacob Helwig% Done:

0%

Category:exec
Target version:2.7.6
Affected Puppet version:2.7.5 Branch:https://github.com/jhelwig/puppet/tree/tickets/2.7.x/9996-exec-resources-with-multiline-commands
Keywords:exec, multi-line customer

We've Moved!

Ticket tracking is now hosted in JIRA: https://tickets.puppetlabs.com

This issue is currently not available for export. If you are experiencing the issue described below, please file a new ticket in JIRA. Once a new ticket has been created, please add a link to it that points back to this Redmine ticket.


Description

‘Test’ works, ‘Test2’ does not. I think that this worked in 2.7.4.

exec { "test":
      command =>  "/bin/echo '#Test' > /tmp/foo; /bin/echo 'bob' >> /tmp/foo;"
}

exec { "test2":
      command =>  "/bin/echo '#Test' > /tmp/foo;
                   /bin/echo 'bob' >> /tmp/foo;"
}

History

#1 Updated by Trevor Vaughan about 3 years ago

Apparently, adding a ‘\’ to the end of each line makes it function properly.

However, this is not a good solution.

#2 Updated by Alexandre Fouche about 3 years ago

I have the same or similar problem, but since i use here-documents, ‘\’ at end of line is not an option.

I have a define, which basically does a /bin/cat of an here-document to a file. It has always worked until puppet-2.7.3 included, but fails with 2.7.4 and 2.7.5. It uses parameter variables, but i can see in debug mode that they are correctly known and expanded.

Here is the define:

define filesection($file, $sectionname, $lines='', $ensure = 'present') {
   case $ensure {
      present: {
         exec { "exec add ${sectionname} $file":
            path => ["/bin", "/usr/bin" ],
            command => "/bin/cat <<EOF >>'${file}'

## PUPPET BEGIN ${sectionname}
${lines}
## PUPPET END ${sectionname}
EOF",
            unless => "grep -qFx '## PUPPET BEGIN ${sectionname}' '${file}'"
         }
      }
# (...)
   }
}

Here is the calling line:

filesection { 'bashrc-shopt-expand_aliases':
    file        => '/etc/bashrc',
    sectionname => 'shopt-expand_aliases',
    lines       => 'shopt -s expand_aliases',
}

And here is the behaviour of different Puppet versions:

2.7.3:

notice: /Stage[os]/Bashrc::Shopt::Expand_aliases/Filesection[bashrc-shopt-expand_aliases]/Exec[exec add shopt-expand_aliases /etc/bashrc]/returns: executed successfully

2.7.4 and 2.7.5 rpms:

debug: Exec[exec add shopt-expand_aliases /etc/bashrc](provider=posix): Executing check 'grep -qFx '## PUPPET BEGIN shopt-expand_aliases' '/etc/bashrc''
debug: Executing 'grep -qFx '## PUPPET BEGIN shopt-expand_aliases' '/etc/bashrc''
debug: Exec[exec add shopt-expand_aliases /etc/bashrc](provider=posix): Executing '/bin/cat <<EOF >>'/etc/bashrc'

## PUPPET BEGIN shopt-expand_aliases
shopt -s expand_aliases
## PUPPET END shopt-expand_aliases
EOF'
debug: Executing '/bin/cat <<EOF >>'/etc/bashrc'

## PUPPET BEGIN shopt-expand_aliases
shopt -s expand_aliases
## PUPPET END shopt-expand_aliases
EOF'
err: /Stage[os]/Bashrc::Shopt::Expand_aliases/Filesection[bashrc-shopt-expand_aliases]/Exec[exec add shopt-expand_aliases /etc/bashrc]/returns: change from notrun to 0 failed: /bin/cat <<EOF >>'/etc/bashrc'

## PUPPET BEGIN shopt-expand_aliases
shopt -s expand_aliases
## PUPPET END shopt-expand_aliases
EOF returned 1 instead of one of [0] at /etc/puppet/environments/production/manifests/classes/filesection.pp:15

#3 Updated by James Turnbull about 3 years ago

  • Category set to exec
  • Status changed from Unreviewed to Needs Decision
  • Assignee set to Nigel Kersten

I can replicate this regression too. Suspect changes in the exec provider caused it.

#4 Updated by Nigel Kersten about 3 years ago

  • Status changed from Needs Decision to Accepted
  • Assignee deleted (Nigel Kersten)
  • Target version set to 2.7.x

Just as a note, I tested whether flipping the provider to explicitly be “posix” or “shell” changes things, and it doesn’t.

#5 Updated by Yuri Arabadji about 3 years ago

Thus breaking my sed 2liners completely. Thanks for that.

#6 Updated by Jacob Helwig about 3 years ago

  • Assignee set to Jacob Helwig

#7 Updated by Jacob Helwig about 3 years ago

This should fix things:

diff --git i/lib/puppet/util.rb w/lib/puppet/util.rb
index 80ce963..a264a0a 100644
--- i/lib/puppet/util.rb
+++ w/lib/puppet/util.rb
@@ -244,7 +244,12 @@ module Util

   def execute_posix(command, arguments, stdin, stdout, stderr)
     child_pid = Kernel.fork do
-      command = Array(command)
+      # We can't just call Array(command), and rely on it returning
+      # things like ['foo'], when passed ['foo'], because
+      # Array(command) will call command.to_a internally, which when
+      # given a string can end up doing Very Bad Things(TM), such as
+      # turning "/tmp/foo;\r\n /bin/echo" into ["/tmp/foo;\r\n", " /bin/echo"]
+      command = [command].flatten
       Process.setsid
       begin
         $stdin.reopen(stdin)

#8 Updated by Jacob Helwig about 3 years ago

  • Status changed from Accepted to In Topic Branch Pending Review
  • Branch set to https://github.com/jhelwig/puppet/tree/tickets/2.7.x/9996-exec-resources-with-multiline-commands

Opened pull request 167 with the fix mentioned earlier, and unit and acceptance tests.

#9 Updated by Josh Cooper about 3 years ago

  • Status changed from In Topic Branch Pending Review to Merged - Pending Release

#10 Updated by Michael Stahnke about 3 years ago

  • Status changed from Merged - Pending Release to Closed

Cherry picked into 2.7rc. Released as part of 2.7.6rc3.

#11 Updated by Matthaus Owens almost 3 years ago

  • Target version changed from 2.7.x to 2.7.6

#12 Updated by Charlie Sharpsteen over 1 year ago

  • Keywords changed from exec, multi-line to exec, multi-line customer

Also available in: Atom PDF