Hi, I have written a sample manifest in puppet using Ruby DSL. I want to build a looping functionality. But I am getting problem as shown below: root@puppet-swproxy:/tmp# cat test.rb hostclass :test do $abc = ["a","b"] $abc.each do |sip| create_resource :exec, "echoabc", :command => "echo #{sip}" end file "/tmp/testecho.txt", :content => "This is test file", :require => Exec[''echoabc''] end node "default" do include "test" end root@puppet-swproxy:/tmp# puppet apply --verbose test.rb Duplicate definition: Exec[echoabc] is already defined on node puppet- swproxy.persistent.co.in I can make the echoabc as dynamic, but how can specify that in require in next statement (file). I need to execute the file only after executing the exec. So what I need to do. Generall the puppet will not run in the synchronized way. I observed that the statements are executed asynchronously. Also, I need to define the Exec path at the top as I specified in the pp file. Exec { path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"], } How to write this in Ruby DSL. So that I can eliminate the path attribute in all exec statements. Thanks in advance, Sateesh B. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
On Feb 8, 4:11 am, sateesh <bbalasate...@gmail.com> wrote:> Hi, > > I have written a sample manifest in puppet using Ruby DSL. I want to > build a looping functionality. But I am getting problem as shown > below: > > root@puppet-swproxy:/tmp# cat test.rb > hostclass :test do > $abc = ["a","b"] > $abc.each do |sip| > create_resource :exec, "echoabc", :command => "echo #{sip}" > end > > file "/tmp/testecho.txt", :content => "This is test file", :require => > Exec[''echoabc''] > end > > node "default" do > include "test" > end > root@puppet-swproxy:/tmp# puppet apply --verbose test.rb > Duplicate definition: Exec[echoabc] is already defined on node puppet- > swproxy.persistent.co.inThis is not a problem with looping per se. In fact, it shows that your looping construct is itself working exactly the way it should.> I can make the echoabc as dynamic,And you need to do that, because every resource in the compiled catalog needs a distinct title.> but how can specify that in require > in next statement (file). I need to execute the file only after > executing the exec.You need to manage the file only after executing *which* Exec? You declare two distinct ones, even if you try to give them the same title.> So what I need to do. Generall the puppet will not > run in the synchronized way. I observed that the statements are > executed asynchronously.Puppet runs completely synchronously, but the order in which it applies resources is essentially unpredictable in the absence of declared resource relationships. That''s very different from asynchronous operation, which would mean that Puppet applies multiple resources concurrently (i.e. via threads or multiple child processes), which it absolutely does not do. If you only need one Exec, then move its declaration out of the loop and all will be well. If you need multiple Execs, and you need them all to run before the file is managed, then create an array before the loop, in your loop add each Exec to it, and make your file require the whole array.> Also, I need to define the Exec path at the top as I specified in the > pp file. > > Exec { > path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"], > } > > How to write this in Ruby DSL. So that I can eliminate the path > attribute in all exec statements.Is there some reason why you actually need to use Ruby DSL instead of Puppet DSL? I don''t see one in what you presented so far, and I would definitely stick to Puppet DSL unless you have no alternative. Here''s one way to implement your example in Puppet DSL: modules/test/manifests/exececho.pp: ------ define test::exececho() { exec { "echo_${name}": command => "echo ${name}", path => [''/bin'', ''/sbin'', ''/usr/bin'', ''/usr/sbin''], tag => test_tag, } } modules/test/manifests/init.pp: ------ class test { test::exececho { [''a'', ''b'']: } file { ''/tmp/testecho.txt'': content => "This is test file" } Exec<| tag == ''test_tag'' |> -> File[''/tmp/testecho.txt''] } If you needed the resource defaults for other Execs as well, then you you could define them at the top of class ''test'' instead of in the test::exececho definition, and they would apply to all Exec resources declared within the scope of class ''test''. If you want those defaults to be global (defaults) for all Execs in your configuration, then just put the resource defaults in site.pp, outside any class. John John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Hi John, Thank you for your response. I am using the Ruby DSL, as I need to loop some exec commands for which there will be some IP adress array that will be passed. Please find below my actual code: hostclass :swift::proxy-ring do require "swift::common" $storage_local_net_ip = [''IP1'',''IP2''] #this may contain n number of IPs. $zone = 0 $storage_local_net_ip.each do |sip| $zone = $zone + 1 # adding entries to each ring create_resource :exec, "ring_account_entry", :command => "swift-ring-builder account.builder add z#{$zone}- #{sip}:6002/sdb1 100", :cwd => "/etc/swift", :require => Class[''swift::proxy-install''], :returns => [0,1], :path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"] create_resource :exec, "ring_container_entry", :command => "swift-ring-builder container.builder add z#{$zone}- #{sip}:6001/sdb1 100", :cwd => "/etc/swift", :require => Class[''swift::proxy-install''], :returns => [0,1], :path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"] create_resource :exec, "ring_object_entry", :command => "swift-ring-builder object.builder add z#{$zone}- #{sip}:6000/sdb1 100", :cwd => "/etc/swift", :require => Class[''swift::proxy-install''], :returns => [0,1], :path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"] end end so, How can we write this in Puppet DSL. Please give me a sample for this. I am newbie to Puppet. So I am unable to understand how to loop this. Thanks, Sateesh B. On Feb 8, 9:50 pm, jcbollinger <John.Bollin...@stJude.org> wrote:> On Feb 8, 4:11 am, sateesh <bbalasate...@gmail.com> wrote: > > > > > Hi, > > > I have written a sample manifest in puppet using Ruby DSL. I want to > > build a looping functionality. But I am getting problem as shown > > below: > > > root@puppet-swproxy:/tmp# cat test.rb > > hostclass :test do > > $abc = ["a","b"] > > $abc.each do |sip| > > create_resource :exec, "echoabc", :command => "echo #{sip}" > > end > > > file "/tmp/testecho.txt", :content => "This is test file", :require => > > Exec[''echoabc''] > > end > > > node "default" do > > include "test" > > end > > root@puppet-swproxy:/tmp# puppet apply --verbose test.rb > > Duplicate definition: Exec[echoabc] is already defined on node puppet- > > swproxy.persistent.co.in > > This is not a problem with looping per se. In fact, it shows that > your looping construct is itself working exactly the way it should. > > > I can make the echoabc as dynamic, > > And you need to do that, because every resource in the compiled > catalog needs a distinct title. > > > but how can specify that in require > > in next statement (file). I need to execute the file only after > > executing the exec. > > You need to manage the file only after executing *which* Exec? You > declare two distinct ones, even if you try to give them the same > title. > > > So what I need to do. Generall the puppet will not > > run in the synchronized way. I observed that the statements are > > executed asynchronously. > > Puppet runs completely synchronously, but the order in which it > applies resources is essentially unpredictable in the absence of > declared resource relationships. That''s very different from > asynchronous operation, which would mean that Puppet applies multiple > resources concurrently (i.e. via threads or multiple child processes), > which it absolutely does not do. > > If you only need one Exec, then move its declaration out of the loop > and all will be well. If you need multiple Execs, and you need them > all to run before the file is managed, then create an array before the > loop, in your loop add each Exec to it, and make your file require the > whole array. > > > Also, I need to define the Exec path at the top as I specified in the > > pp file. > > > Exec { > > path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"], > > } > > > How to write this in Ruby DSL. So that I can eliminate the path > > attribute in all exec statements. > > Is there some reason why you actually need to use Ruby DSL instead of > Puppet DSL? I don''t see one in what you presented so far, and I would > definitely stick to Puppet DSL unless you have no alternative. Here''s > one way to implement your example in Puppet DSL: > > modules/test/manifests/exececho.pp: > ------ > define test::exececho() { > exec { "echo_${name}": > command => "echo ${name}", > path => [''/bin'', ''/sbin'', ''/usr/bin'', ''/usr/sbin''], > tag => test_tag, > } > > } > > modules/test/manifests/init.pp: > ------ > class test { > test::exececho { [''a'', ''b'']: } > > file { ''/tmp/testecho.txt'': > content => "This is test file" > } > > Exec<| tag == ''test_tag'' |> -> File[''/tmp/testecho.txt''] > > } > > If you needed the resource defaults for other Execs as well, then you > you could define them at the top of class ''test'' instead of in the > test::exececho definition, and they would apply to all Exec resources > declared within the scope of class ''test''. If you want those defaults > to be global (defaults) for all Execs in your configuration, then just > put the resource defaults in site.pp, outside any class. > > John > > John-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Sateesh, It is better if you don''t look at it as a "loop." A loop is a very procedural concept. You are working with a machine that you are trying to get into a fixed state. So better to think "I want to have a bunch of similar-looking resources that are identified and enumerated in an array." This leads you to defined types: http://docs.puppetlabs.com/learning/definedtypes.html Which is probably the way you should do this. -Eric -- Eric Shamow Professional Services http://puppetlabs.com/ (c)631.871.6441 On Wednesday, February 8, 2012 at 11:46 PM, sateesh wrote:> Hi John, > > Thank you for your response. > > I am using the Ruby DSL, as I need to loop some exec commands for > which there will be some IP adress array that will be passed. Please > find below my actual code: > > hostclass :swift::proxy-ring do > require "swift::common" > > $storage_local_net_ip = [''IP1'',''IP2''] #this may contain n number of > IPs. > > $zone = 0 > $storage_local_net_ip.each do |sip| > $zone = $zone + 1 > # adding entries to each ring > create_resource :exec, "ring_account_entry", > :command => "swift-ring-builder account.builder add z#{$zone}- > #{sip}:6002/sdb1 100", > :cwd => "/etc/swift", > :require => Class[''swift::proxy-install''], > :returns => [0,1], > :path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"] > > create_resource :exec, "ring_container_entry", > :command => "swift-ring-builder container.builder add z#{$zone}- > #{sip}:6001/sdb1 100", > :cwd => "/etc/swift", > :require => Class[''swift::proxy-install''], > :returns => [0,1], > :path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"] > > create_resource :exec, "ring_object_entry", > :command => "swift-ring-builder object.builder add z#{$zone}- > #{sip}:6000/sdb1 100", > :cwd => "/etc/swift", > :require => Class[''swift::proxy-install''], > :returns => [0,1], > :path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"] > end > > end > > so, How can we write this in Puppet DSL. Please give me a sample for > this. I am newbie to Puppet. So I am unable to understand how to loop > this. > > Thanks, > Sateesh B. > > On Feb 8, 9:50 pm, jcbollinger <John.Bollin...@stJude.org (http://stJude.org)> wrote: > > On Feb 8, 4:11 am, sateesh <bbalasate...@gmail.com (http://gmail.com)> wrote: > > > > > > > > > Hi, > > > > > I have written a sample manifest in puppet using Ruby DSL. I want to > > > build a looping functionality. But I am getting problem as shown > > > below: > > > > > > > > > > root@puppet-swproxy:/tmp# cat test.rb > > > hostclass :test do > > > $abc = ["a","b"] > > > $abc.each do |sip| > > > create_resource :exec, "echoabc", :command => "echo #{sip}" > > > end > > > > > > > > > > file "/tmp/testecho.txt", :content => "This is test file", :require => > > > Exec[''echoabc''] > > > end > > > > > > > > > > node "default" do > > > include "test" > > > end > > > root@puppet-swproxy:/tmp# puppet apply --verbose test.rb > > > Duplicate definition: Exec[echoabc] is already defined on node puppet- > > > swproxy.persistent.co.in (http://swproxy.persistent.co.in) > > > > > > > > > This is not a problem with looping per se. In fact, it shows that > > your looping construct is itself working exactly the way it should. > > > > > I can make the echoabc as dynamic, > > > > And you need to do that, because every resource in the compiled > > catalog needs a distinct title. > > > > > but how can specify that in require > > > in next statement (file). I need to execute the file only after > > > executing the exec. > > > > > > > > > You need to manage the file only after executing *which* Exec? You > > declare two distinct ones, even if you try to give them the same > > title. > > > > > So what I need to do. Generall the puppet will not > > > run in the synchronized way. I observed that the statements are > > > executed asynchronously. > > > > > > > > > Puppet runs completely synchronously, but the order in which it > > applies resources is essentially unpredictable in the absence of > > declared resource relationships. That''s very different from > > asynchronous operation, which would mean that Puppet applies multiple > > resources concurrently (i.e. via threads or multiple child processes), > > which it absolutely does not do. > > > > If you only need one Exec, then move its declaration out of the loop > > and all will be well. If you need multiple Execs, and you need them > > all to run before the file is managed, then create an array before the > > loop, in your loop add each Exec to it, and make your file require the > > whole array. > > > > > Also, I need to define the Exec path at the top as I specified in the > > > pp file. > > > > > > > > > > Exec { > > > path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"], > > > } > > > > > > > > > > How to write this in Ruby DSL. So that I can eliminate the path > > > attribute in all exec statements. > > > > > > > > > Is there some reason why you actually need to use Ruby DSL instead of > > Puppet DSL? I don''t see one in what you presented so far, and I would > > definitely stick to Puppet DSL unless you have no alternative. Here''s > > one way to implement your example in Puppet DSL: > > > > modules/test/manifests/exececho.pp: > > ------ > > define test::exececho() { > > exec { "echo_${name}": > > command => "echo ${name}", > > path => [''/bin'', ''/sbin'', ''/usr/bin'', ''/usr/sbin''], > > tag => test_tag, > > } > > > > } > > > > modules/test/manifests/init.pp: > > ------ > > class test { > > test::exececho { [''a'', ''b'']: } > > > > file { ''/tmp/testecho.txt'': > > content => "This is test file" > > } > > > > Exec<| tag == ''test_tag'' |> -> File[''/tmp/testecho.txt''] > > > > } > > > > If you needed the resource defaults for other Execs as well, then you > > you could define them at the top of class ''test'' instead of in the > > test::exececho definition, and they would apply to all Exec resources > > declared within the scope of class ''test''. If you want those defaults > > to be global (defaults) for all Execs in your configuration, then just > > put the resource defaults in site.pp, outside any class. > > > > John > > > > John > > -- > You received this message because you are subscribed to the Google Groups "Puppet Users" group. > To post to this group, send email to puppet-users@googlegroups.com (mailto:puppet-users@googlegroups.com). > To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com (mailto:puppet-users+unsubscribe@googlegroups.com). > For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en. > >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
On 02/09/2012 05:50 AM, Eric Shamow wrote:> Sateesh, > > It is better if you don''t look at it as a "loop." A loop is a very > procedural concept. You are working with a machine that you are trying > to get into a fixed state. > > So better to think "I want to have a bunch of similar-looking resources > that are identified and enumerated in an array." > > This leads you to defined > types: http://docs.puppetlabs.com/learning/definedtypes.html > > Which is probably the way you should do this.+1 Be especially aware that you need a "creates" or "onlyif" constraint, otherwise puppet will perform your exec through each run. Here''s a pointer: define proxy_ring($sip) { exec { "account-for-zone$name": command => "swift-ring-builder account.builder add z$name-$sip:6002/sdb1 100", creates => ?????????! cwd => "/etc/swift", require => Class[''swift::proxy-install''], path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"]; "containter-for-zone$name": ... } Use this like proxy_ring { "1": $ip1; "2": $ip2; ... } If you prefer arrays - that''s harder. You could store the definitions in a hash and use the create_resources() function. HTH, Felix -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Hi Felix, Thanks for the help. I have solved it another way. In my case the array is dynamic. My scripts should support any number of IPs. Initially we dont know that. The user will set the array in the site.pp and run the scripts. Our modules should rnu according to the length of the array. So here proxy_ring { "1": $ip1; "2": $ip2; ... } We cannot hardcode the parameters. However, I have solved that in different manner. I have used the John''s comment "Exec<| tag == ''test_tag'' |> -> File[''/ tmp/testecho.txt''] " statement to tell the dependency to the Ruby DSL. Thanks everybody who helped me. Thanks, Sateesh B. On Feb 9, 1:39 pm, Felix Frank <felix.fr...@alumni.tu-berlin.de> wrote:> On 02/09/2012 05:50 AM, Eric Shamow wrote: > > > Sateesh, > > > It is better if you don''t look at it as a "loop." A loop is a very > > procedural concept. You are working with a machine that you are trying > > to get into a fixed state. > > > So better to think "I want to have a bunch of similar-looking resources > > that are identified and enumerated in an array." > > > This leads you to defined > > types:http://docs.puppetlabs.com/learning/definedtypes.html > > > Which is probably the way you should do this. > > +1 > > Be especially aware that you need a "creates" or "onlyif" constraint, > otherwise puppet will perform your exec through each run. > > Here''s a pointer: > > define proxy_ring($sip) { > exec { "account-for-zone$name": > command => "swift-ring-builder account.builder add > z$name-$sip:6002/sdb1 100", > creates => ?????????! > cwd => "/etc/swift", > require => Class[''swift::proxy-install''], > path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"]; > "containter-for-zone$name": > ... > > } > > Use this like > proxy_ring { > "1": $ip1; > "2": $ip2; > ... > > } > > If you prefer arrays - that''s harder. You could store the definitions in > a hash and use the create_resources() function. > > HTH, > Felix-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.