3

Problem

Puppet split function fails since Puppet has been upgraded puppet to version 3.5.1, while this worked until 3.4.3

Code

 1  $ports_regex = "80\\|443"
 2
 3  $ports_string       = regsubst($ports_regex, '\\\|', ',', 'G')
 4
 5  notify{"CP1 ${ports_string}":}
 6
 7  $ports_array = split($ports_string, ',')
 8
 9  notify{"CP2 ${ports_array}":}
10
11  each($ports_array) |$port| {
12      notify{"CP3 ${port}":}
13
14      file {"${port}":
15          path => "c:/temp/puppettest/${port}",
16          ensure => present;
17      }
18  }

Outcome

3.4.3

Notice: /Stage[main]/Main/File[443]/ensure: created
Notice: CP2 80443
Notice: /Stage[main]/Main/Notify[CP2 80443]/message: defined 'message' as 'CP2 80443'
Notice: CP1 80,443
Notice: /Stage[main]/Main/Notify[CP1 80,443]/message: defined 'message' as 'CP1 80,443'
Notice: CP3 80
Notice: /Stage[main]/Main/Notify[CP3 80]/message: defined 'message' as 'CP3 80'
Notice: /Stage[main]/Main/File[80]/ensure: created
Notice: CP3 443
Notice: /Stage[main]/Main/Notify[CP3 443]/message: defined 'message' as 'CP3 443'

3.5.1

C:\Windows\system32>puppet apply --parser future --debug --verbose "C:\temp\puppettest\site.pp"
Error: Invalid tag cp2  at C:/temp/puppettest/site.pp:9 on node ...
Error: Invalid tag cp2  at C:/temp/puppettest/site.pp:9 on node ...

Question

How to solve this issue?

  • Can we get some line numbers here? What exactly is on line 9 of your site.pp? Is line 9 the split() call? – Zoredache Apr 30 '14 at 22:48
  • I have added line numbers as well – 030 May 1 '14 at 6:46
  • It may be a regression in the future parser. You may wish to bring this up with the dev team. – Felix Frank May 5 '14 at 16:29
  • It seems that the split function neither works in 3.5.1, nor in 3.6.0. An issue has been created at Puppet Labs. – 030 May 18 '14 at 9:18
1

Ticket closed and marked as "won't fix", see https://tickets.puppetlabs.com/browse/PUP-2612

Henrik Lindberg added a comment - 2014/05/19 3:43 PM - edited

Ah, the next issue is that interpolation of hashes and arrays produce their source equivalent text where it used to just run all the content together.

You can see that if you compare the following with the current and future parsers:

$a = [1,2,3]

notice $a

notice "$a"

I am not sure what you are trying to achieve here - the original seems to have created "CP 2 80443", and you now get "CP2 [80, 443]" which it then barfs on. Then when you iterate of $ports_array, you will get a $port that is first 80 and then 443 (when the regexp has been corrected with 6 backslashes). This means you put 2 notify in the catalog; "CP3 80", and then "CP3 443", and then creates 2 file resources, one titled "80", and then one titled "443".

The Resource implementation is responsible for the interpretation of the title string, and it does odd things when facing punctuation, spaces, numbers and brackets.

Tip is to use notice to get output with intermediate results. I used this for the first part:

$ports_regex = "80\|443"

$ports_string = regsubst($ports_regex, '\\\|', ',', 'G')

notice "ports_regex = '${ports_regex}'"

notice "ports_string = '${ports_string}'"

$ports_array = split($ports_string, ',')

notice "ports_array = '${ports_array}'"

$a = "CP1 ${ports_string}"

notice $a

notify{$a:}

$b = "CP2 ${ports_array}"

notice $b

notify{$b:}

If you want the old behavior of simply running all the content of the array together into one string without any separators, you should use the join function in stdlib (i.e. join($ports_array, ''), but then you could just do that with a separate substitute of the commas.

You can also do this in a different order - something like:

$ports_array = $ports_regex.split('\\\|')

$ports_string = $ports_array.join('')

The first splits the string into an array, and the second constructs a string with the numbers joined without punctuation and brackets. You can then use that string to interpolate into the titles starting with CP.

Or if you do not want to type so many backslashes, you can use a regexp directly:

$ports_array = $ports_regex.split(/\|/)

$ports_string = $ports_array.join('')

Hope that helps

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.