Re: [Puppet Users] About the params pattern
Hi, Le 19/09/2014 17:36, jcbollinger a écrit : The main points I am trying to get across And I thnink that you have succeeded now. ;) are these: 1. References to *non-local* variables should always be performed via qualified names, even when class inheritance makes the variable in question accessible also via its unqualified name. 2. All qualified names used should accurately reflect the location of the referenced entity's declaration (some variables have multiple, distinct qualified names). 3. If a class or defined type refers to a variable belonging to a different class then it should ensure via 'include' / 'require' / 'contain' or via class inheritance that the variable is initialized first. It's very clear. Thanks. I am not saying that references to variables declared *locally* should use qualified names, but if you want to adopt that practice then it's fine. With respect to other classes' variables, though, I seem not to be successfully communicating point (2). Now I have understood the 3 rules. I use $::test::xxx in class::internal not $::test::params::xxx because when xxx is var1 or var2, I want to have the value of var1 and var2 given as parameters of the test class (I don't want the default value of var1 and var2). Yes, that's fine for var1 and var2, but not for foo1 and foo2 which are not declared by class test. I don't see any particular purpose for foo1 and foo2 to live in test::params anyway, however, if they are not to be used as class parameter defaults. You could as easily put them directly in class test, and then continue to refer to them as you are now doing. Yes, it's good idea. Finally, as regards your comments, I think follow this pattern where I follow your 3 rules, it seems ;): - # Example of declaration for the test class. class { test: var1 = 'specific_var1', } test module with its classes class test::params { # API of the module with the default values. $var1 = 'default_var1' $var2 = 'default_var2' } # The *main* class of the module class test ( $var1 = $::test::params::var1, $var2 = $::test::params::var2, ) inherits test::params { # Shared variables in all classes of the module. $foo1 = 'value_foo1' $foo2 = 'value_foo2' include ::test::internal # Here, I could use $var1, $var2, $foo1, $foo2 # (only in the main class of the module). notify { 'v1': message = var1 = $::test::var1, } notify { 'v2': message = var2 = $::test::var2, } notify { 'f1': message = foo1 = $::test::foo1, } notify { 'f2': message = foo2 = $::test::foo2, } # etc. } class test::internal { # It's an internal class of the module test which will be # never called by the user. So, the line below is useless. # It's just for self-documenting. # Maybe I could remove this line, I don't know... require ::test notify { 'iv1': message = Internal var1 = $::test::var1, } notify { 'iv2': message = Internal var2 = $::test::var2, } notify { 'if1': message = Internal foo1 = $::test::foo1, } notify { 'if2': message = Internal foo2 = $::test::foo2, } # So, in templates, I use the syntax scope['::test::var'] file { '/tmp/internal.txt': content = inline_template(var1=%= scope['::test::var1'] %\nfoo2=%= scope['::test::foo2'] %\n), } } - By the way, don't be confused about the meaning of the 'include' statement, or its siblings 'require' and 'contain'. 'Include' says that the named class must be included *in the catalog*; it does NOT interpolate the named class's body in place of the include statement (i.e. it is not analogous to a C preprocessor #include directive). A given class can be the subject of any number of 'include', 'require', and 'contain' statements; no class will appear in the catalog more than once. Yes, it's clear and even clearer with your link below. In part, it looks like you are running into bug 1220 https://tickets.puppetlabs.com/browse/PUP-1220. Yes, this is exactly my problem! That was reported fixed in Puppet 3.5.0, but if I understand correctly, you need to enable the future parser to actually activate the bug fix (which would make the variable reference in your template fail to resolve in both cases). I confirm. If I put: parser = future in the puppet.conf (in [main] section), I have the expected behaviour. To my mind, the execpted behaviour (explained in the puppet documentation) occurs with parser = future which is *not* enabled by default. It's curious, but not a problem for me. I guess it's a backward compatibility problem... And in this case, I don't understand. I thought that : $var1 = value_var1 # LINE A include ::test::internal # LINE B and include ::test::internal # LINE B $var1 = value_var1 # LINE A was completely equivalent. Am I wrong?
Re: [Puppet Users] About the params pattern
What you've stumbled on is the concept of public and private classes. Public and private classes are implemented very differently. A public class is your module's entry point, this is how people interact with your module. A public class is where you define your module's API. Private classes, on the other hand, are not meant to be called outside your module. Private classes are the meat of your module. This is where you will actually implement your module's functionality. A public class should be the only way a user can interact with your private classes. Public classes should generally do very little. I typically limit my public classes to validating the inputs received by my parameters and calling my private classes. Since examples speak louder than words, here's an example: # my_module/manifests/init.pp class my_module ( $var1 = $my_module::params::var1, $var2 = $my_module::params::var2, $var3 = $my_module::params::var3, ) inherits my_module::params { # Validate my parameters validate_string($var1) validate_array($var2) validate_bool($var3) # Call my 'private' classes class { 'my_module::install': } - class {'my_module::config': } ~ class {'my_module::service'} - Class['my_module'] } The 'my_module' class is my public class. It has three parameters. All this class does is validate my three parameters and call my private classes. Let's take a look at those private classes: # my_module/manifests/install.pp class my_module::install ( $var1 = $my_module::var1, $var2 = $my_module::var2, ) { private() # Body of the class ... } # my_module/manifests/config.pp class my_module::config ( $var2 = $my_module::var2, $var3 = $my_module::var3, ) { private() # Body of the class ... } # my_module/manifests/service.pp class my_module::service ( $var1 = $my_module::var1, $var2 = $my_module::var2, $var3 = $my_module::var3, ) { private() # Body of the class ... } As you can see, I've marked my private classes with the private function. This function has not yet been released in stdlib, but is available in trunk (https://github.com/puppetlabs/puppetlabs-stdlib#private). Google can show you how to implement this functionality in the DSL, if you prefer. The private classes concept allows us to make some assumptions that affect the design of this module, specifically, calling the variables in my_module without inheriting it first. We're assuming that, since this is a private class, it will not be called independently of my_module, and those variables will always be accessible. This pattern can be found in a number of modules on the forge. Note, that these modules don't use the private function since it hasn't been released yet. They assume that the private classes are only being called inside their module. Here are some examples: https://github.com/garethr/garethr-docker https://github.com/puppetlabs/puppetlabs-mysql https://github.com/puppetlabs/puppetlabs-ntp This is emerging very quickly as a good design pattern that fosters modularity, simplicity, good separation of concerns, and clear data flow. On Monday, September 22, 2014 4:01:19 AM UTC-7, François Lafont wrote: Hi, Le 19/09/2014 17:36, jcbollinger a écrit : The main points I am trying to get across And I thnink that you have succeeded now. ;) are these: 1. References to *non-local* variables should always be performed via qualified names, even when class inheritance makes the variable in question accessible also via its unqualified name. 2. All qualified names used should accurately reflect the location of the referenced entity's declaration (some variables have multiple, distinct qualified names). 3. If a class or defined type refers to a variable belonging to a different class then it should ensure via 'include' / 'require' / 'contain' or via class inheritance that the variable is initialized first. It's very clear. Thanks. I am not saying that references to variables declared *locally* should use qualified names, but if you want to adopt that practice then it's fine. With respect to other classes' variables, though, I seem not to be successfully communicating point (2). Now I have understood the 3 rules. I use $::test::xxx in class::internal not $::test::params::xxx because when xxx is var1 or var2, I want to have the value of var1 and var2 given as parameters of the test class (I don't want the default value of var1 and var2). Yes, that's fine for var1 and var2, but not for foo1 and foo2 which are not declared by class test. I don't see any particular purpose for foo1 and foo2 to live in test::params anyway, however, if they are not to be used as class parameter defaults. You could as easily put them directly in class test, and then continue to refer to them as you are now doing. Yes, it's good idea.
Re: [Puppet Users] About the params pattern
What you've stumbled on is the concept of public and private classes. Public and private classes are implemented very differently. A public class is your module's entry point, this is how people interact with your module. A public class is where you define your module's API. Private classes, on the other hand, are not meant to be called outside your module. Private classes are the meat of your module. This is where you will actually implement your module's functionality. A public class should be the only way a user can interact with your private classes. Public classes should generally do very little. I typically limit my public classes to validating the inputs received by my parameters and calling my private classes. Since examples speak louder than words, here's an example: # my_module/manifests/init.pp class my_module ( $var1 = $my_module::params::var1, $var2 = $my_module::params::var2, $var3 = $my_module::params::var3, ) inherits my_module::params { # Validate my parameters validate_string($var1) validate_array($var2) validate_bool($var3) # Call my 'private' classes class { 'my_module::install': } - class {'my_module::config': } ~ class {'my_module::service'} - Class['my_module'] } The 'my_module' class is my public class. It has three parameters. All this class does is validate my three parameters and call my private classes. Let's take a look at those private classes: # my_module/manifests/install.pp class my_module::install ( $var1 = $my_module::var1, $var2 = $my_module::var2, ) { private() # Body of the class ... } # my_module/manifests/config.pp class my_module::config ( $var2 = $my_module::var2, $var3 = $my_module::var3, ) { private() # Body of the class ... } # my_module/manifests/service.pp class my_module::service ( $var1 = $my_module::var1, $var2 = $my_module::var2, $var3 = $my_module::var3, ) { private() # Body of the class ... } As you can see, I've marked my private classes with the private function. This function has not yet been released in stdlib, but is available in trunk (https://github.com/puppetlabs/puppetlabs-stdlib#private). Google can show you how to implement this functionality in the DSL, if you prefer. The private classes concept allows us to make some assumptions that affect the design of this module, specifically, calling the variables in my_module without inheriting it first. We're assuming that, since this is a private class, it will not be called independently of my_module, and those variables will always be accessible. This pattern can be found in a number of modules on the forge. Note, that these modules don't use the private function since it hasn't been released yet. They assume that the private classes are only being called inside their module. Here are some examples: https://github.com/garethr/garethr-docker https://github.com/puppetlabs/puppetlabs-mysql https://github.com/puppetlabs/puppetlabs-ntp This is emerging very quickly as a good design pattern that fosters modularity, simplicity, good separation of concerns, and clear data flow. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/95a01d6a-f6b0-48bd-b47b-bf9ab99773e0%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Example of how to use require with hiera?
Does this actually work Nan?? Can somebody point me to any page where this is documented? Toni On Friday, September 19, 2014 6:33:07 PM UTC+2, Nan Liu wrote: On Thu, Sep 18, 2014 at 6:19 PM, Daniel Johnson tekn...@gmail.com javascript: wrote: Things like require: File['somefile'] or require: File: somefile both crash, and burn. Not having a require also causes failure as it tries to do things it can't without the prerequisite. After hours of searching I couldn't find any examples to work from. If you are building a resource hash for create_resources, it's just quoted string: --- notify: example1: message: first example2: message: second require: Notify[example1] create_resources(notify, hiera('notify')) HTH, Nan -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/f8042e80-fa4d-45cd-892e-d46afd234a15%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] class/subclass relationship ordering and containment
On Friday, September 19, 2014 7:37:57 PM UTC-5, Nan Liu wrote: TLDR summary: 1. include/require class does not provide containment. 2. anchor is just a empty resource for containment. 3. contain class provides containment without the need for anchor 4. contain may cause unnecessary relationship, so use it only when appropriate 5. The original purpose for inherits, resource parameter override, is rarely used. These days it's mostly a hack to have module data. classes inherit params class which only contain puppet variables and no resources. (I won't get into this and only focus on the previous points) On Fri, Sep 19, 2014 at 4:01 PM, Mike Reed mjohn...@gmail.com javascript: wrote: Hello all, I have a question about class and subclass relationships and what is/isn't the ideal way to go about such a thing. Please bear with me as I'm still refining my understanding of containment. Let's say I have a puppet module which manages the install of puppet and has the following pieces (currently using puppet v.3.4.3): *init.pp* class puppet { # evaluate supporting classes include puppet::params include puppet::config include puppet::service anchor { 'puppet::begin' : } - class { '::puppet::params' : } - class { '::puppet::config' : } ~ class { '::puppet::service' : } - anchor { 'puppet::end' : } } *params.pp* class puppet::params { # puppet general params $puppet_path= '/etc/puppet' $puppet_config_template = 'puppet/puppet.conf.erb' $puppet_package = 'puppet' $puppet_common_package = 'puppet-common' $puppet_service_ensure = 'running' $puppet_service_enable = true $puppet_prod_version= '3.6.2-1puppetlabs1' $puppet_dev_version = '3.6.2-1puppetlabs1' validate_string($puppet_path) validate_string($puppet_config_template) validate_string($puppet_package) validate_string($puppet_common_package) validate_string($puppet_service_ensure) validate_bool($puppet_service_enable) validate_string($puppet_prod_version) validate_string($puppet_dev_version) validate don't serve any purpose here, since you setting these values to a specific value. } *config.pp* class puppet::config ( $puppet_config_path = $::puppet::params::puppet_config_path, $puppet_config_template = $::puppet::params::puppet_config_template, $puppet_service = $::puppet::params::puppet_service, ) inherits puppet::params { file { 'puppet.conf' : ensure = present, path= ${puppet_config_path}/, content = template(${puppet_config_template}), notify = Service[${puppet_service}], } } *service.pp* class puppet::service ( $puppet_package = $::puppet::params::puppet_package, ***truncated variables for sake of a long post*** ) inherits puppet::config { package { ${puppet_package}: ensure = ${puppet_prod_version}, } package { ${puppet_common_package}: ensure = ${puppet_prod_version}, } service { ${puppet_service}: ensure = ${puppet_service_ensure}, name = ${puppet_service}, enable = ${puppet_service_enable}, hasrestart = true, hasstatus = true, subscribe = Package[${puppet_config_template}], } } Based on the above, I've left a few things which I feel don't belong but for the sake of my questions, they're included. Per the above init.pp, I've added an anchor to force ordering. My understanding is that this has nothing to do with application-order and more to do with parse-order. With that said, I have a few questions: The anchor is not parse-order, it to server as a ghost containment resource for the class. I re-emphasize that point. The Anchor pattern has NOTHING to do with parse / evaluation order, exactly contrary to the OP's assertion. It is only relevant to client-side order of resource application. The syntax short hand is what confusing. You can totally rewrite as following: class { '::puppet::params' : require = Anchor['puppet::begin']} class { '::puppet::config' : } ~ class { '::puppet::service' : before = Anchor['puppet::end']} anchor { ['puppet::begin', 'puppet::end']: } Although that does have exactly the same application-order implications as the OP's version, it has slightly different evaluation / catalog-building semantics, owing to the use of resource-like class declarations in place of 'include' / 'require' / 'contain'. That probably does not matter for this example, but it might matter in some other cases. 1. By adding the 'include' in init.pp, my understanding is that simply says to 'evaluate' the subclasses but does not indicate an order to which subclasses are to be applied. Is that correct? Mostly. 2. I think the 'inherits' function is depreciated but should each instance be replaced with a 'contain' (based on the order I want) throughout my subclass
Re: [Puppet Users] Manage a single file (directory) from multiple modules
On Saturday, September 20, 2014 2:33:34 PM UTC-5, aar...@gmail.com wrote: Thanks Neil, I am not sure I understand exactly what you mean, so I will post the code I have done for testing (I am using different paths, but the concept is the same as the original post). Here is the class with the define. It is in a module called copy_directory. class copy_directory { } define managed_preferences ($source = undef) { file {/tmp/: source = puppet:///modules/${source}/tmp, recurse = true, owner = root, group = root, mode= 600, } } Here is the module that calls it. include copy_directory class test_module { managed_preferences { 'title': source = $module_name, } } I also created a module called test_module2 with the same code. I know that file {/tmp/: is causing the problem, but the entire point is different modules copy files into that directory. To me I'm defining it once, and using it twice. As I defined it in the copy_directory module, and I am using it in the test_module and test_module2. What am I doing wrong? A class may be declared multiple times (though the resource-like syntax, if used, must be the first one evaluated), with the same effect as declaring it just once. That is, classes are idempotent. Ordinary resources, including defined-type instance, may be declared only once. Given that defined types are usually meant to allow multiple instances, it follows that defined type instances must declare only resources that wholly belong to them; they must not not declare shared resources. Instead, they can rely on a class to declare the shared resources. For example: class my_module::preferences_base { # A shared resource: file { '/etc/preferences': ensure = 'directory', owner = 'root', owner = 'group', mode = '0644' } } define my_module::preference_file($source) { # relies on the preferences base directory: include 'my_module::preferences_base' # A file in the preferences base directory: file { /etc/preferences/${title}: ensure = 'file', source = $source, owner = 'root', owner = 'group', mode = '0644' } } That should also work if the the shared directory is managed recursively, or if the defined type declares a directory instead of a file -- even a recursively managed one. Does that help? John -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/8fa2ad9b-3a5a-44ff-a94f-4197314961f5%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Syntax error
Hi Folks, I've tried this snippet several ways, both using case and selector statements. I keep getting an error root@ubuntu64:/etc/puppet/manifests# puppet parser validate /etc/puppet/modules/timezone/manifests/params.pp Error: Could not parse for environment production: Syntax error at '='; expected '}' at /etc/puppet/modules/timezone/manifests/params.pp:25 root@ubuntu64:/etc/puppet/manifests# comments above have been taken out 15 class timezone::params { 16 17 $timezone = 'Australia/Darwin' 18 $hw_utc = true 19 20 # This is calculated in timezone class 21 $set_timezone_command = '' 22 23 case $::operatingsystem { 24 /^(?i:Debian|Ubuntu)$/: { 25 $config_file = '/etc/timezone' 26 } 27 /^(?i:RedHat|CentOS)$/: { 28 case $::operatingsystemmajrelease { 29 '7': $config_file = '/etc/localtime' 30 default: $config_file = '/etc/sysconfig/clock' 31 } 32 } 33 default: { $config_file = '/etc/sysconfig/clock' } 34 } 35 36 $config_file_mode = $::operatingsystem ? { 37 default = '0644', 38 } 39 40 $config_file_owner = $::operatingsystem ? { 41 default = 'root', 42 } 43 44 $config_file_group = $::operatingsystem ? { 45 'FreeBSD' = 'wheel', 46 default = 'root', 47 } 48 49 $source = '' 50 $template = timezone/timezone-${::operatingsystem} 51 $options = '' 52 $audit_only = false 53 $noops = false 54 55 } If somebody wouldn't mind pointing out the error my ways, that would be most appreciated. Thanks David -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/d580879f-1db3-478a-beee-73a81657cb14%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Re: Resource ordering of Execs not working as expected
On Friday, September 19, 2014 12:59:34 PM UTC-5, Jake Lundberg wrote: Puppet 3.6.2 First, I understand that Execs try not to run multiple times if called many times by many resources and typically wait until they've all been collected from all resources Not exactly. Execs run at most twice per Puppet run. They run at most once if they are refreshonly or if they do not receive any events from other resources. (If they are refreshonly then they run *only* if they receive an event from another resource.) When they run relative to when other resources are applied (and whether resources send them events) is shaped by resource relationships, just as with all other resource types. ObYoda: Do... or do not. There is no 'try'. , but I have a specific case where I need different Execs to run in a particular order based on a set of resources that change. That's what resource relationships are for. Cristian has showed you how. If that doesn't seem to be working for you then it would help us help you if you present a complete -- but simple -- example that demonstrates your problem. John -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/9a9f750a-3cf8-4d62-90ed-409c0d10d22e%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Re: Unable to do puppet apply nodes.pp
Hello Felix, I'l upgrade my Puppet master and client to 3.7.1. Thanks, Justin. On Sun, Sep 21, 2014 at 8:10 PM, Felix Frank felix.fr...@alumni.tu-berlin.de wrote: On 09/21/2014 07:25 PM, Justin Timberlake wrote: But the strange thing is that when i checked the Puppet webconsole, the path shown in the logs is that of the environment *i.e /etc/puppet/environments/production/manifests/.* Inconclusive. I suspect that this may be some compatibility setting affecting you in weird ways. Please do consider updating to 3.7.1. Best, Felix -- You received this message because you are subscribed to a topic in the Google Groups Puppet Users group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/puppet-users/g1sFQ9-HqzE/unsubscribe. To unsubscribe from this group and all its topics, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/541F22BD.5000206%40Alumni.TU-Berlin.de https://groups.google.com/d/msgid/puppet-users/541F22BD.5000206%40Alumni.TU-Berlin.de?utm_medium=emailutm_source=footer . For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/CAGVZ_irDH887gwy8fBYzr1W6-SirzCrawBXcMOShASy3r-1YKA%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Re: Cross-module variables and mix-and-match with Hiera
On Friday, September 19, 2014 3:45:17 PM UTC-5, Kimo Rosenbaum wrote: Hello, I'm using puppet 3 with roles (mostly), profiles, and Hiera. I have a profile setup (for pdxcat/collectd) to, amongst other things, hiera_array() for values [of localports] to pass on to collectd::plugin::tcpconns. Defining everything in hiera files works as expected. However, I would like to add to those values from other profiles. But I haven't been able to get that working. Any suggestions? I don't think its possible to approach the problem as you are trying to do. Even if you could, you shouldn't create cross-profile dependencies like you are trying to do. Instead, it is the job of the role to provide everything needed to integrate all the profiles. You could do it via the role class instead of in Hiera, however. That makes sense to me, because the role classes are where the information of which profiles are involved is stored. Perhaps you could add a parameter to profiles::collectd by which the role can provide the needed data, which it would assemble from class variables of the profile classes. John -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/72363009-bd6c-41b8-8c2a-5e97826df44b%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Globally used parameter
On Friday, September 19, 2014 2:25:34 PM UTC-5, Jose Luis Ledesma wrote: Using hiera is probably the best solution. So that would mean creating 'server' as an hiera item, and having each class that wanted it look it up as $server = hiera('server') That's basically the property file approach. An alternative would be to choose one class to be the owner of the data, and have all the other classes involved use that. The chosen class could be one of the existing ones, or it could be a separate one, possibly in a different module: class settings::network { $port = 1234 } class server::config { $listen_port = $::settings::network::port } Do understand, however, that cross-module variable references are considered poor form by many, as they undermine modularity. Inter-class variable references are better limited to classes in the same module. John -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/6b5f7df1-57b0-4e34-83c2-536c86e9889e%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] About the params pattern
Hi, Le 22/09/2014 15:16, David Danzilio a écrit : What you've stumbled on is the concept of public and private classes. Not exactly I think. The concept of public and private classes was clear for me. It was the *implementation* of the params pattern which was not clear for me, especially for private classes. I think it's ok now. ;) Public and private classes are implemented very differently. A public class is your module's entry point, this is how people interact with your module. A public class is where you define your module's API. Private classes, on the other hand, are not meant to be called outside your module. Private classes are the meat of your module. This is where you will actually implement your module's functionality. A public class should be the only way a user can interact with your private classes. Public classes should generally do very little. I typically limit my public classes to validating the inputs received by my parameters and calling my private classes. Totally agree with that. No problem. Since examples speak louder than words, here's an example: # my_module/manifests/init.pp class my_module ( $var1 = $my_module::params::var1, $var2 = $my_module::params::var2, $var3 = $my_module::params::var3, ) inherits my_module::params { # Validate my parameters validate_string($var1) validate_array($var2) validate_bool($var3) # Call my 'private' classes class { 'my_module::install': } - class {'my_module::config': } ~ class {'my_module::service'} - Class['my_module'] } The 'my_module' class is my public class. It has three parameters. All this class does is validate my three parameters and call my private classes. Let's take a look at those private classes: # my_module/manifests/install.pp class my_module::install ( $var1 = $my_module::var1, $var2 = $my_module::var2, ) { private() # Body of the class ... } # my_module/manifests/config.pp class my_module::config ( $var2 = $my_module::var2, $var3 = $my_module::var3, ) { private() # Body of the class ... } # my_module/manifests/service.pp class my_module::service ( $var1 = $my_module::var1, $var2 = $my_module::var2, $var3 = $my_module::var3, ) { private() # Body of the class ... } Ok, it looks like what I gave in my previous message except: 1. the private() function. I didn't know it. 2. In my case, in a private class, I don't use parameters and I use the variables of the public class directly with the fully qualified name : class my_module::service { notify { var1 = $::my_module::var1: } # etc. } Thus, I don't have to write the parameters of the public class for *each* private class. But, in return, I have to use the fully the qualified names of these variables. ;) As you can see, I've marked my private classes with the private function. This function has not yet been released in stdlib, but is available in trunk (https://github.com/puppetlabs/puppetlabs-stdlib#private). Thank you. Very interesting. Google can show you how to implement this functionality in the DSL, if you prefer. The private classes concept allows us to make some assumptions that affect the design of this module, specifically, calling the variables in my_module without inheriting it first. We're assuming that, since this is a private class, it will not be called independently of my_module, and those variables will always be accessible. This pattern can be found in a number of modules on the forge. Note, that these modules don't use the private function since it hasn't been released yet. They assume that the private classes are only being called inside their module. Here are some examples: https://github.com/garethr/garethr-docker https://github.com/puppetlabs/puppetlabs-mysql https://github.com/puppetlabs/puppetlabs-ntp This is emerging very quickly as a good design pattern that fosters modularity, simplicity, good separation of concerns, and clear data flow. Ok, thanks for your remarks. François Lafont -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/54204073.9060906%40gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] About the params pattern
On 09/18/2014 04:40 PM, jcbollinger wrote: I'm not prepared to set up and run this test, but if it genuinely produces the results you describe then that demonstrates a bug. Here are the docs on Puppet scope: https://docs.puppetlabs.com/puppet/3/reference/lang_scope.html. Here are the docs on referencing variables from templates: https://docs.puppetlabs.com/guides/templating.html#referencing-variables. Inasmuch as this is one of the more heavily used areas of Puppet, I suspect that something else is going on in your environment, but if such a bug has indeed cropped up then I'm sure PuppetLabs would appreciate a bug report. Aw man, that thread is way too voluminous for me to read in a spare minute. But since you bring up templates - there was that bug, yes. https://tickets.puppetlabs.com/browse/PUP-1220 It led to dynamic scoping rearing its ugly head again, when variables were used in templates. Not sure if this is the issue here, but it might. The OP can verify this by setting parser=future. Cheers, Felix -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/54204A86.3030707%40Alumni.TU-Berlin.de. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Re: class/subclass relationship ordering and containment
Hey Nan and John, Thank you both for the replies and insight into my questions below; they are most helpful and very much appreciated. Based on your answers, I have few other questions that occurred to me: In response to my question about inherits, John had mentioned this below: If you don't need the variables of the params class for class parameter defaults, however, then you can replace inheritance with 'include'ing (or 'require'ing or 'contain'ing) the params class it the start of erstwhile child class's body. In my example config.pp, I'm using things like $puppet_config_path = $::puppet::params::puppet_config_path, which obviously points to my params.pp file and thus would in theory, pull the variable value and evaluate accordingly. If I am indeed pointing these local variables to my params.pp, it doesn't seem obvious that I need any include or inhert to params.pp in my subclasses. In this example, I do indeed need the variables from my params class for my subclass defaults but because I'm specifically calling these with the use of local variables, is it advisable to still include the params.pp subclass? It seems that my manifests would be more tidy if I didn't have include/inherits littered throughout my subclasses. Further, if I had a selector or case statement in my params.pp, they it would seem appropriate to include params.pp in my config.pp because I indeed do need that selector/case statement to be evaluated before the config.pp subclass can be completed. Am I thinking about this correctly? Lastly, it seems that in the case of any module with subclasses, I want and need to include class/subclass ordering or the sake of ordering sanity. In your opinion, should I be including subclass ordering in my init.pp for each module I write (assuming it includes subclasses)? Thank you guys for your invaluable information and for you patience. Cheers, Mike On Friday, September 19, 2014 4:01:28 PM UTC-7, Mike Reed wrote: Hello all, I have a question about class and subclass relationships and what is/isn't the ideal way to go about such a thing. Please bear with me as I'm still refining my understanding of containment. Let's say I have a puppet module which manages the install of puppet and has the following pieces (currently using puppet v.3.4.3): *init.pp* class puppet { # evaluate supporting classes include puppet::params include puppet::config include puppet::service anchor { 'puppet::begin' : } - class { '::puppet::params' : } - class { '::puppet::config' : } ~ class { '::puppet::service' : } - anchor { 'puppet::end' : } } *params.pp* class puppet::params { # puppet general params $puppet_path= '/etc/puppet' $puppet_config_template = 'puppet/puppet.conf.erb' $puppet_package = 'puppet' $puppet_common_package = 'puppet-common' $puppet_service_ensure = 'running' $puppet_service_enable = true $puppet_prod_version= '3.6.2-1puppetlabs1' $puppet_dev_version = '3.6.2-1puppetlabs1' validate_string($puppet_path) validate_string($puppet_config_template) validate_string($puppet_package) validate_string($puppet_common_package) validate_string($puppet_service_ensure) validate_bool($puppet_service_enable) validate_string($puppet_prod_version) validate_string($puppet_dev_version) } *config.pp* class puppet::config ( $puppet_config_path = $::puppet::params::puppet_config_path, $puppet_config_template = $::puppet::params::puppet_config_template, $puppet_service = $::puppet::params::puppet_service, ) inherits puppet::params { file { 'puppet.conf' : ensure = present, path= ${puppet_config_path}/, content = template(${puppet_config_template}), notify = Service[${puppet_service}], } } *service.pp* class puppet::service ( $puppet_package = $::puppet::params::puppet_package, ***truncated variables for sake of a long post*** ) inherits puppet::config { package { ${puppet_package}: ensure = ${puppet_prod_version}, } package { ${puppet_common_package}: ensure = ${puppet_prod_version}, } service { ${puppet_service}: ensure = ${puppet_service_ensure}, name = ${puppet_service}, enable = ${puppet_service_enable}, hasrestart = true, hasstatus = true, subscribe = Package[${puppet_config_template}], } } Based on the above, I've left a few things which I feel don't belong but for the sake of my questions, they're included. Per the above init.pp, I've added an anchor to force ordering. My understanding is that this has nothing to do with application-order and more to do with parse-order. With that said, I have a few questions: 1. By adding the 'include' in init.pp, my understanding is that simply says to 'evaluate' the subclasses but does not indicate an order to which subclasses are to be
Re: [Puppet Users] About the params pattern
Le 22/09/2014 18:12, Felix Frank a écrit : Aw man, that thread is way too voluminous for me to read in a spare minute. Yes, sorry. It's a long thread but it's a finished thread I think. ;) But since you bring up templates - there was that bug, yes. https://tickets.puppetlabs.com/browse/PUP-1220 It led to dynamic scoping rearing its ugly head again, when variables were used in templates. Not sure if this is the issue here, but it might. The OP can verify this by setting parser=future. Yes, I have confirmed here: ;) On Monday, September 22, 2014 4:01:19 AM UTC-7, François Lafont wrote: I confirm. If I put: parser = future in the puppet.conf (in [main] section), I have the expected behaviour. To my mind, the execpted behaviour (explained in the puppet documentation) occurs with parser = future which is *not* enabled by default. It's curious, but not a problem for me. I guess it's a backward compatibility problem... François Lafont -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/54204C36.2060608%40gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Example of how to use require with hiera?
Does this actually work Nan?? It does work. At least in the latest version of puppet. Can somebody point me to any page where this is documented? If I could find documentation for it I wouldn't have asked here. -- teknotus (Take Notice) -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/CA%2BnDE0iqZzFn6-UKwEa4tQTKPEgJdj5f%2BTZfUGE%2Bu8s--UtmFg%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] About the params pattern
On 09/22/2014 06:20 PM, Francois Lafont wrote: But since you bring up templates - there was that bug, yes. https://tickets.puppetlabs.com/browse/PUP-1220 It led to dynamic scoping rearing its ugly head again, when variables were used in templates. Not sure if this is the issue here, but it might. The OP can verify this by setting parser=future. Yes, I have confirmed here: ;) \o/ Thanks -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/54204DD0.1080004%40Alumni.TU-Berlin.de. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Manage a single file (directory) from multiple modules
Thanks John, By putting the /etc/preferences/${title} in the file line, aren't you putting a subfolder in the preferences folder on the puppet agent? I tried to follow your example and it happened to me. What I am looking to do is to have different modules writing into the base folder, in your example /etc/preferences/. The modules won't ever have the same file names, so overwritting isn't a concern. Is this possible? On Monday, September 22, 2014 9:33:04 AM UTC-5, jcbollinger wrote: On Saturday, September 20, 2014 2:33:34 PM UTC-5, aar...@gmail.com wrote: Thanks Neil, I am not sure I understand exactly what you mean, so I will post the code I have done for testing (I am using different paths, but the concept is the same as the original post). Here is the class with the define. It is in a module called copy_directory. class copy_directory { } define managed_preferences ($source = undef) { file {/tmp/: source = puppet:///modules/${source}/tmp, recurse = true, owner = root, group = root, mode= 600, } } Here is the module that calls it. include copy_directory class test_module { managed_preferences { 'title': source = $module_name, } } I also created a module called test_module2 with the same code. I know that file {/tmp/: is causing the problem, but the entire point is different modules copy files into that directory. To me I'm defining it once, and using it twice. As I defined it in the copy_directory module, and I am using it in the test_module and test_module2. What am I doing wrong? A class may be declared multiple times (though the resource-like syntax, if used, must be the first one evaluated), with the same effect as declaring it just once. That is, classes are idempotent. Ordinary resources, including defined-type instance, may be declared only once. Given that defined types are usually meant to allow multiple instances, it follows that defined type instances must declare only resources that wholly belong to them; they must not not declare shared resources. Instead, they can rely on a class to declare the shared resources. For example: class my_module::preferences_base { # A shared resource: file { '/etc/preferences': ensure = 'directory', owner = 'root', owner = 'group', mode = '0644' } } define my_module::preference_file($source) { # relies on the preferences base directory: include 'my_module::preferences_base' # A file in the preferences base directory: file { /etc/preferences/${title}: ensure = 'file', source = $source, owner = 'root', owner = 'group', mode = '0644' } } That should also work if the the shared directory is managed recursively, or if the defined type declares a directory instead of a file -- even a recursively managed one. Does that help? John -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/99ac011e-153b-4675-825f-575fd81bf911%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Puppet Master Profiles - Crosspost from Puppet-dev
Hello, We are interested in collecting puppet profile data from the puppet master in the real world. This data will be used to help us find a direction to go to increase the throughput of the puppet master master. I've created a script that will create a yaml file that will have various system facts and profile data that you will need to generate from a master. To generate this data follow the steps listed below. 1. Download the profiler script from https://github.com/demophoon/puppet-master-profiler 2. Run your puppet master with the `--debug`, `--profile`, and `--logdest=path_to_a_blank_file` flags 3. Wait for a few agents to check-in. You can tail the log file to see agents checking in to the master. 4. From the repository run `profile.rb path_to_log_file`. The log file will the the same path as the one specified above. 5. Answer the questions on screen and email the result file to me at br...@puppetlabs.com. If you would like to do so send the apache log files for the time that the puppet master was running as well, it will help us see how the agent acts during the profile. We realize that some may not be comfortable doing this so it is completely optional. If you have any questions or concerns please feel free to ask them here! Thank you, Britt Gresham -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/4888c822-028d-4262-b80f-f6074d56c888%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Re: Resource ordering of Execs not working as expected (SOLVED)
Hrm, well, with your help, I got this to work in the order I was expecting. I think I had a few problems here. 1. My original ordering was: File['Config'] - Exec['stop'] - Package['foo'] - Exec['start'] I changed this to: File['Config'] ~ Exec['stop'] - Package['foo'] ~ Exec['start'] It helps when I RTFM on using ~ for notifications instead of - for pure ordering. 2. When I wasn't using that ordering syntax, I had: exec { stop: path= /usr/local/sbin/:/usr/local/jdk/bin:/bin:/sbin:/usr/sbin:/usr/bin, command = '/usr/local/sbin/control.sh stop', refreshonly = true, logoutput = true, subscribe = File['Config'], require = File['/usr/local/sbin/control.sh'] } This is because there are cases when the foo::config is created, but foo is not (meaning the control files are not created). I figured this would create the proper order, but it doesn't seem to have. 3. Using different types of configuration patterns. I kept flipping between using subscribe/notify and -/~ ordering syntax and most likely screwed something up in the interim. I eventually made a mistake and got some dependency cycle issues which actually helped quite a bit in figuring out my error in logic. BTW, refreshonly = true is still set on both execs and is working properly. Thank you for the help!!! Jake On Monday, September 22, 2014 7:44:34 AM UTC-7, jcbollinger wrote: On Friday, September 19, 2014 12:59:34 PM UTC-5, Jake Lundberg wrote: Puppet 3.6.2 First, I understand that Execs try not to run multiple times if called many times by many resources and typically wait until they've all been collected from all resources Not exactly. Execs run at most twice per Puppet run. They run at most once if they are refreshonly or if they do not receive any events from other resources. (If they are refreshonly then they run *only* if they receive an event from another resource.) When they run relative to when other resources are applied (and whether resources send them events) is shaped by resource relationships, just as with all other resource types. ObYoda: Do... or do not. There is no 'try'. , but I have a specific case where I need different Execs to run in a particular order based on a set of resources that change. That's what resource relationships are for. Cristian has showed you how. If that doesn't seem to be working for you then it would help us help you if you present a complete -- but simple -- example that demonstrates your problem. John -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/7a4f2132-2f53-47bf-afb1-80e5d25988d5%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Adding basic user accounts via Puppet to Linux systems (minor problem)
We have a need to have the same login accounts exist on several old/legacy systems internally (older systems, won't be connected to LDAP for a variety of reasons). Reading around, it seemed like a simple task to do, using the virtual users and realize functions: @user { username: require = Group['staff'], ensure = present, uid = , gid = 90, password= '$1$OMITTED.', groups = wheel, shell = '/bin/bash', home= '/home/username', managehome = true, } file { /home/username: ensure = directory, recurse = false, purge = false, owner = 6332, group = 90, require = User['username'], } # Realize users Group | title == staff | - User | title == username | It works for 4 out of 5 users; the other, puppet doesn't transfer the password into the shadow file. I've pored over and there are no typos. The hash is the correct length. Instead, the shadow password for this user ends up being !!. I remove the user from passwd, shadow and the homeir and this still happens, regardless. The hash ends in a / (slash) and I wonder if that might be tripping Puppet up. That's the only thing I can think of. Also, if you happen to change the password field, that doesn't get updated forward, which is not the behavior I expected. Thanks. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/f9f9504b-757f-4024-807c-1f76d47c7eef%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Puppet 3.7.1 parse problems with resource overrides.
So, new behavior that I'm not sure is intentional. File['blah'] works fine, File ['blah'] is now illegal - the additional whitespace causes the below stupendously readable error on puppet parser validate. Error: Could not parse for environment production: Expression is not valid as a resource, resource-default, or resource-override at (slice () 'file'):(slice () 'line'):(slice ([] (cat '' (str $myvar) '')) 'pos') Is this a known bug I've failed to find on the ticket system, or intended behavior I've just missed in the notes? If not, I'll go chase it as a bug. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/8c2ca98f-55a2-4be1-9504-e24607f48656%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Automatically cleaning up if a class/define is no longer used (related to purging unmanaged resources)
Hello, I have a question about automatically cleaning configuration if the class/define that generated it is no longer used. For example, I have a number of logging daemons that I would like to be able to disable automatically if their definitions are removed from the node's manifest: node foo { # bar and baz are actually names of pre-define logging # configurations statlog knows what to do with statlog { bar:} statlog { baz:} } This, basically, creates, starts, and enables (on boot) two new services statlog.bar and statlog.baz. So far so good. Now, because statlog can be resource-intensive, suppose I would like the statlog.baz service to be stopped and disabled automatically if I remove statlog { baz:} from the manifest: site.pp: node foo { statlog { bar:} } Since there are many possible statlogs, I don't want to make site.pp messy by explicitly doing something like the following for every one. site.pp: node foo { statlog { bar:} statlog { baz: purge = true} } Here's roughly what I am thinking of doing (but I am wondering if there is a better way). site.pp: # this is in global area of site.pp. so that all nodes, whether they # use statlog or not include this code class { statlog::autocleanup:} node foo { statlog { bar:} } statlog module: class statlog::autocleanup() { # real implementation is a bit more complicated to handle # resource ordering, non-existent services, etc. if !defined(Service[statlog.baz]) { service{ statlog.baz: ensure = stopped, enable = false, } } if !defined(Service[statlog.foo]) { ... } } Is there a better way to do this? Thanks very much, Vlad -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/542072D9.6050500%40icecube.wisc.edu. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Re: Puppet 3.7.1 parse problems with resource overrides.
One more, mostly just a 'wouldn't it be nice if this were clearly handled?' Having a comma at the end of an assignment like the below appears to cause confusion; mostly at this point my gripe is that the error line is reported as the enclosing class/define/whatever instead of at the line with the errant comma. puppet parser validate --parser=future init.pp Error: Could not parse for environment production: This Array Expression is not productive. A Host Class Definition can not end with a non productive construct at init.pp:1:1 class a { $foo = bar, $banana = apple } On Monday, September 22, 2014 11:48:20 AM UTC-7, Tristan Smith wrote: So, new behavior that I'm not sure is intentional. File['blah'] works fine, File ['blah'] is now illegal - the additional whitespace causes the below stupendously readable error on puppet parser validate. Error: Could not parse for environment production: Expression is not valid as a resource, resource-default, or resource-override at (slice () 'file'):(slice () 'line'):(slice ([] (cat '' (str $myvar) '')) 'pos') Is this a known bug I've failed to find on the ticket system, or intended behavior I've just missed in the notes? If not, I'll go chase it as a bug. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/27b39605-a929-4271-8a4b-b693337b7207%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Manage a single file (directory) from multiple modules
Hello I do not think that is possible or really desirable. Puppet is about desired state so you can not say the directory should both be /pathtodir ├── fileA └── fileB and /tmp should be /pathtodir ├── fileB └── fileC as the first says must not have fileC and the second says must have fileC. Those are conflicting. Back to what you could do, which is to write to two separate directories and then merge them together with a separate command that is triggered by either directory changing. But you should not go down that route especially in a situation like this where you can specify exactly what files you want. Going to your original post what you are trying to do is write the preferences for a particular application in the User Template for that application. Trouble is, looking on my mac, there are multiple plist files there for each application so transform your file { System/Library/User Template/English.lproj/Library/Preferences/: source = puppet:///modules/office_2011/Preferences, owner = root, group = wheel, mode= 600, recurse = true, require = Package[$main_package], } into $components = ['com.microsoft.Excel.plist','com.microsoft.Outlook.plist',] macprefs::usertemplate{ $components: require= Package[$main_package], sourcebase = 'puppet:///modules/office_2011/Preferences', } (or that can be wrapped up into a define for this set of prefs,) now you need to implement macprefs::usertemplate. (I've ignored the language/locale issue which could complicate matters) so now you make a module and in there you do similar things to John's post in a file macprefs/manifest/init.pp start by making /System/Library/User Template class macprefs { # A shared resource: file { '/System/Library/User Template/English.lproj/Library/Preferences': ensure = 'directory', owner = 'root', owner = 'wheel', mode = '0700' } } in a file macprefs/manifest/usertemplate.pp define macprefs::usertemplate($sourcebase, $require) { # relies on the preferences base directory: include 'macprefs' # A file in the templates directory: file { /System/Library/User Template/English.lproj/Library/Preferences /${title}: ensure = 'file', source = $sourcebase/$title, require = $require, owner = 'root', group = 'wheel', mode= '0600' } } Neil On 22 September 2014 17:30, aarb...@gmail.com wrote: Thanks John, By putting the /etc/preferences/${title} in the file line, aren't you putting a subfolder in the preferences folder on the puppet agent? I tried to follow your example and it happened to me. What I am looking to do is to have different modules writing into the base folder, in your example /etc/preferences/. The modules won't ever have the same file names, so overwritting isn't a concern. Is this possible? On Monday, September 22, 2014 9:33:04 AM UTC-5, jcbollinger wrote: On Saturday, September 20, 2014 2:33:34 PM UTC-5, aar...@gmail.com wrote: Thanks Neil, I am not sure I understand exactly what you mean, so I will post the code I have done for testing (I am using different paths, but the concept is the same as the original post). Here is the class with the define. It is in a module called copy_directory. class copy_directory { } define managed_preferences ($source = undef) { file {/tmp/: source = puppet:///modules/${source}/tmp, recurse = true, owner = root, group = root, mode= 600, } } Here is the module that calls it. include copy_directory class test_module { managed_preferences { 'title': source = $module_name, } } I also created a module called test_module2 with the same code. I know that file {/tmp/: is causing the problem, but the entire point is different modules copy files into that directory. To me I'm defining it once, and using it twice. As I defined it in the copy_directory module, and I am using it in the test_module and test_module2. What am I doing wrong? A class may be declared multiple times (though the resource-like syntax, if used, must be the first one evaluated), with the same effect as declaring it just once. That is, classes are idempotent. Ordinary resources, including defined-type instance, may be declared only once. Given that defined types are usually meant to allow multiple instances, it follows that defined type instances must declare only resources that wholly belong to them; they must not not declare shared resources. Instead, they can rely on a class to declare the shared resources. For example: class my_module::preferences_base { # A shared resource: file { '/etc/preferences': ensure = 'directory', owner = 'root', owner = 'group', mode = '0644' } } define my_module::preference_file($source) { # relies on the preferences base directory: include 'my_module::preferences_base' # A file in the preferences base directory:
Re: [Puppet Users] Automatically cleaning up if a class/define is no longer used (related to purging unmanaged resources)
On Mon, Sep 22, 2014 at 02:04:57PM -0500, Vladimir Brik wrote: Hello, I have a question about automatically cleaning configuration if the class/define that generated it is no longer used. For example, I have a number of logging daemons that I would like to be able to disable automatically if their definitions are removed from the node's manifest: node foo { # bar and baz are actually names of pre-define logging # configurations statlog knows what to do with statlog { bar:} statlog { baz:} } You'll have better results by building in some kind of enable=false parameterization. Removing something from the catalog means that puppet no longer manages it, but specifying that a service is stopped will actually implement some result. define statlog ($enabled) { service { statlog_${name}: ensure = $enabled, enable = $enabled, } } This, basically, creates, starts, and enables (on boot) two new services statlog.bar and statlog.baz. So far so good. Now, because statlog can be resource-intensive, suppose I would like the statlog.baz service to be stopped and disabled automatically if I remove statlog { baz:} from the manifest: site.pp: node foo { statlog { bar:} } It's barely resource-intensive to stop something. After it has been stopped for a while you can of course remove it from the manifest with no effect. Since there are many possible statlogs, I don't want to make site.pp messy by explicitly doing something like the following for every one. site.pp: node foo { statlog { bar:} statlog { baz: purge = true} } Here's roughly what I am thinking of doing (but I am wondering if there is a better way). site.pp: # this is in global area of site.pp. so that all nodes, whether they # use statlog or not include this code class { statlog::autocleanup:} node foo { statlog { bar:} } statlog module: class statlog::autocleanup() { # real implementation is a bit more complicated to handle # resource ordering, non-existent services, etc. if !defined(Service[statlog.baz]) { service{ statlog.baz: ensure = stopped, enable = false, } } if !defined(Service[statlog.foo]) { ... } } Is there a better way to do this? I dealt with this by listing things in hiera when I have many similar things. Going on the earlier example, some yaml which you can automatically generate if you have some automated way of listing which statlogs should be enabled and which should not: --- statlogs: foo: bar: enabled: false baz: Then a class: class manystatlogs { $statlogs = hiera('statlogs') $defaults = { enabled = true, } create_resources('statlog', $statlogs, $defaults) } (These days I think the hiera/create_resources functions are easier to use, iffy on the params classes, worried about many lookups with class parameters, topic still unsolved.) Then in your profile or node or whatever: include ::manystatlogs This lets you edit the hiera and leave the code alone. Obviously you're still actively managing things which are not to run, which is how puppet works. Thanks very much, Vlad -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/542072D9.6050500%40icecube.wisc.edu. For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/20140922194247.GA27370%40iniquitous.heresiarch.ca. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Manage a single file (directory) from multiple modules
Thanks Neil, In yours and Johns example you both have ${title} at the end of Preferences. When I tried this (after his post, I haven't tried your code yet), I ended up with a folder called Preferences/office_2011 which defeats the purpose of what I am trying to do. Am I misunderstanding that line? I understand why two modules can't manage the same folder (from a Puppet perspective) but was thinking that all of my modules would send a list of files to the one module that had the ability to write to that folder and it would work. I really appreciate everyone trying to help me, but I guess there is something that I am not understanding, or perhaps I am not explaining myself properly. If I have a variable after Preferences (which I need to prevent the duplicate resource) then how do I get all of my files into the root of that Preference folder? I apologize if your code works the way I am asking, but if it does, then I don't understand what the variable is doing after the word Preference and could use some clarification on that. Also, what is the $components variable mean? Is that a type of function or feature that I can read up on in the documentation? On Monday, September 22, 2014 2:27:44 PM UTC-5, Neil - Puppet List wrote: Hello I do not think that is possible or really desirable. Puppet is about desired state so you can not say the directory should both be /pathtodir ├── fileA └── fileB and /tmp should be /pathtodir ├── fileB └── fileC as the first says must not have fileC and the second says must have fileC. Those are conflicting. Back to what you could do, which is to write to two separate directories and then merge them together with a separate command that is triggered by either directory changing. But you should not go down that route especially in a situation like this where you can specify exactly what files you want. Going to your original post what you are trying to do is write the preferences for a particular application in the User Template for that application. Trouble is, looking on my mac, there are multiple plist files there for each application so transform your file { System/Library/User Template/English.lproj/Library/Preferences/: source = puppet:///modules/office_2011/Preferences, owner = root, group = wheel, mode= 600, recurse = true, require = Package[$main_package], } into $components = ['com.microsoft.Excel.plist','com.microsoft.Outlook.plist',] macprefs::usertemplate{ $components: require= Package[$main_package], sourcebase = 'puppet:///modules/office_2011/Preferences', } (or that can be wrapped up into a define for this set of prefs,) now you need to implement macprefs::usertemplate. (I've ignored the language/locale issue which could complicate matters) so now you make a module and in there you do similar things to John's post in a file macprefs/manifest/init.pp start by making /System/Library/User Template class macprefs { # A shared resource: file { '/System/Library/User Template/English.lproj/Library/Preferences ': ensure = 'directory', owner = 'root', owner = 'wheel', mode = '0700' } } in a file macprefs/manifest/usertemplate.pp define macprefs::usertemplate($sourcebase, $require) { # relies on the preferences base directory: include 'macprefs' # A file in the templates directory: file { /System/Library/User Template/English.lproj/Library/Preferences /${title}: ensure = 'file', source = $sourcebase/$title, require = $require, owner = 'root', group = 'wheel', mode= '0600' } } Neil On 22 September 2014 17:30, aar...@gmail.com javascript: wrote: Thanks John, By putting the /etc/preferences/${title} in the file line, aren't you putting a subfolder in the preferences folder on the puppet agent? I tried to follow your example and it happened to me. What I am looking to do is to have different modules writing into the base folder, in your example /etc/preferences/. The modules won't ever have the same file names, so overwritting isn't a concern. Is this possible? On Monday, September 22, 2014 9:33:04 AM UTC-5, jcbollinger wrote: On Saturday, September 20, 2014 2:33:34 PM UTC-5, aar...@gmail.com wrote: Thanks Neil, I am not sure I understand exactly what you mean, so I will post the code I have done for testing (I am using different paths, but the concept is the same as the original post). Here is the class with the define. It is in a module called copy_directory. class copy_directory { } define managed_preferences ($source = undef) { file {/tmp/: source = puppet:///modules/${source}/tmp, recurse = true, owner = root, group = root, mode= 600, } } Here is the module that calls it. include copy_directory class test_module {
Re: [Puppet Users] Syntax error
Hi, Try $config_file = 'value'. You need to assign the value. https://docs.puppetlabs.com/puppet/latest/reference/lang_conditional.html#case-statements Cheers Den On 22 Sep 2014, at 11:53, David Logan skrat...@gmail.com wrote: Syntax error at '='; expected '}' at /etc/puppet/modules/time -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/20C73C84-E00A-4B36-BF86-2A83A4E4A14D%40gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Manage a single file (directory) from multiple modules
I did the following to see if it would work, and I got (for me anyway) a surprising result. It may be the source of some of my confusion and reason why I'm finding this so difficult. Note, I don't want to do this this way. I just did it as an experiment. define mac_managed_preferences ($source) { include managed_preferences file { /System/Library/User Template/English.lproj/Library/Preferences/${source} : source = puppet:///modules/${source}/Preferences/, owner = root, group = wheel, mode= 600, recurse = true, } exec { Move Preferences: command = mv $source/* ../Preferences/, path= /bin, cwd = /System/Library/User Template/English.lproj/Library/Preferences/, require = File[/System/Library/User Template/English.lproj/Library/Preferences/${source}], } exec { Delete Folder: command = rm -rf $source, path= /bin/, cwd = /System/Library/User Template/English.lproj/Library/Preferences/, require = Exec[Move Preferences], } } Here is the relevant portion of the module that installs the application. mac_managed_preferences { $module_name: source = $module_name, } I got an error: Duplicate declaration [Move Preferences] is already declared in file (path to managed_preferences file) cannot redeclare at (path to same file). In my previous posts I said that I though that I accessed the module multiple times, but declared it once, but this message is making me understand that puppet says I was declaring it multiple times, but I am unsure how. I know two modules are accessing it, but felt that was what I was supposed to do. To make things more confusing, the command has a variable in it (which is why it didn't error on the file part), but the working directory is static and is causing the problem. But what if my command was just ls would it complain about the same cwd when it would cause no harm? How does puppet know what my command would do anyway? What am I not understanding in this example that is causing the redeclaring error? Is it the same principle in the other posts where the file resource was causing the problem? On Monday, September 22, 2014 2:58:52 PM UTC-5, aar...@gmail.com wrote: Thanks Neil, In yours and Johns example you both have ${title} at the end of Preferences. When I tried this (after his post, I haven't tried your code yet), I ended up with a folder called Preferences/office_2011 which defeats the purpose of what I am trying to do. Am I misunderstanding that line? I understand why two modules can't manage the same folder (from a Puppet perspective) but was thinking that all of my modules would send a list of files to the one module that had the ability to write to that folder and it would work. I really appreciate everyone trying to help me, but I guess there is something that I am not understanding, or perhaps I am not explaining myself properly. If I have a variable after Preferences (which I need to prevent the duplicate resource) then how do I get all of my files into the root of that Preference folder? I apologize if your code works the way I am asking, but if it does, then I don't understand what the variable is doing after the word Preference and could use some clarification on that. Also, what is the $components variable mean? Is that a type of function or feature that I can read up on in the documentation? On Monday, September 22, 2014 2:27:44 PM UTC-5, Neil - Puppet List wrote: Hello I do not think that is possible or really desirable. Puppet is about desired state so you can not say the directory should both be /pathtodir ├── fileA └── fileB and /tmp should be /pathtodir ├── fileB └── fileC as the first says must not have fileC and the second says must have fileC. Those are conflicting. Back to what you could do, which is to write to two separate directories and then merge them together with a separate command that is triggered by either directory changing. But you should not go down that route especially in a situation like this where you can specify exactly what files you want. Going to your original post what you are trying to do is write the preferences for a particular application in the User Template for that application. Trouble is, looking on my mac, there are multiple plist files there for each application so transform your file { System/Library/User Template/English.lproj/Library/Preferences/: source = puppet:///modules/office_2011/Preferences, owner = root, group = wheel, mode= 600, recurse = true, require = Package[$main_package], } into $components = ['com.microsoft.Excel.plist', 'com.microsoft.Outlook.plist',] macprefs::usertemplate{ $components: require= Package[$main_package], sourcebase = 'puppet:///modules/office_2011/Preferences', } (or that can be wrapped up into a
[Puppet Users] Learn Puppet: Quest Guide, manual install of puppetlabs-apache-0.8.1.tar.gz results in 1 dependency cycle
I'm following through the Learn Puppet Quest guide. At The Puppet Forge section, task 1 is to install the puppetlabs-apache module. My VM does not have access to the internet so the puppet module install puppetlabs-apache command fails. the guide says to untar the /usr/src/forge/puppetlabs-apache-0.8.1.tar.gz file. (That file contained an HTML file with a 301 Moved Permanently message so I downloaded the file from https://github.com/puppetlabs/puppetlabs-apache/releases instead.) After un-taring the file, and moving it to /etc/puppetlabs/puppet/modules/apache, I started the PE console and added the lvmguide. Then I ran the puppet agent --test command to cause the agent to apply the puppet configuration. The result is: ... Info: Loading facts in /var/opt/lib/pe-puppet/lib/facter/ip6tables_version.rb Info: Loading facts in /var/opt/lib/pe-puppet/lib/facter/staging_http_get.rb Info: Loading facts in /var/opt/lib/pe-puppet/lib/facter/puppet_vardir.rb Info: Loading facts in /var/opt/lib/pe-puppet/lib/facter/iptables_version.rb Info: Loading facts in /var/opt/lib/pe-puppet/lib/facter/pe_build.rb Info: Loading facts in /var/opt/lib/pe-puppet/lib/facter/pe_puppetdb_server_status.rb Info: Caching catalog for learn.localdomain Info: Applying configuration version '1411417411' Error: Could not apply complete catalog: Found 1 dependency cycle: (File[/var/www/html/lvmguide] = File[25-learning.puppetlabs.vm.conf] = Service[httpd] = Class[Apache] = File[/var/www/html/lvmguide]) Cycle graph written to /var/opt/lib/pe-puppet/state/graphs/cycles.dot. Notice: Finished catalog run in 19.30 seconds Any ideas as to why the tutorial would result in a dependency cycle? I googled the problem and found the question asked but not answered. Any help is appreciated. Thx, Mark -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/7fc1f737-06c2-4c95-9fbb-51b021a879ca%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Virtual users and group gids
When creating users from hiera, it's simple enough to make them all virtual using create_resources and then realize them. This does leave me with a question, though. How do I make sure that the assorted groups associated with each user are created with the proper gid? I don't see any easy way to define If this group is created, use this gid in puppet. Am I missing something? -- Robert Davidson -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/1EE73329D6577F44A3C2FB0F7D4ACAE98CC1A914%40MBX-02.WIN.NOMINUM.COM. For more options, visit https://groups.google.com/d/optout.
[Puppet Users] Puppet 3.6.2 package gem provider unable to update r10k gem
I have Puppet 3.6.2 on CentOS 7 server acting as Puppetmaster. I had r10k 1.2.1 installed and I changed my ensure to 1.3.4. My other Puppetmaster running CentOS 6 had no problem with this (except for NOTICE output being printed as an error). The CentOS 7 system fails with the following: Debug: Executing '/usr/bin/gem install -v 1.3.4 --no-rdoc --no-ri r10k ' Error: Could not update: Execution of '/usr/bin/gem install -v 1.3.4 --no-rdoc --no-ri r10k ' returned 1: ERROR: Can't use --version w/ multiple gems. Use name:ver instead. snip trace output Error: /Stage[main]/R10k::Install/Package[r10k]/ensure: change from [1.2.1] to 1.3.4 failed: Could not update: Execution of '/usr/bin/gem install -v 1.3.4 --no-rdoc --no-ri r10k ' returned 1: ERROR: Can't use --version w/ multiple gems. Use name:ver instead. If I run that gem install command outside Puppet, on the same server, it works just fine. # /usr/bin/gem install -v 1.3.4 --no-rdoc --no-ri r10k Fetching: r10k-1.3.4.gem (100%) NOTICE == If you are upgrading from 1.1.0 and are using multiple sources, please read this. (If not, feel free to continue with your regularly scheduled day.) GH-48 (https://github.com/adrienthebo/r10k/issues/48) introduced the ability for environments to be prefixed with the source name so that multiple sources installed into the same directory would not overwrite each other. However prefixing was automatically enabled and would break existing setups where multiple sources were cloned into different directories. Because this introduced a breaking change, SemVer dictates that the automatic prefixing has to be rolled back. Prefixing can be enabled but always defaults to off. If you are relying on this behavior you will need to update your r10k.yaml to enable prefixing on a per-source basis. Please see the issue (https://github.com/adrienthebo/r10k/issues/48) for more information. Successfully installed r10k-1.3.4 1 gem installed # echo $? 0 - Trey -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/b3dbd100-1a14-4b79-a41b-a11950761355%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [Puppet Users] Re: Tidy symlinks
tidy doesn't set a flag that would be required by Fileset in order to follow symlinks (:links = :follow) so the behavior is consistent with stat (http://linux.die.net/man/2/stat) In my case I had some fun with /etc/init.d which is a symlink to /etc/rc.d/init.d I created https://tickets.puppetlabs.com/browse/PUP-3328 for this and added a patch. On Friday, July 24, 2009 4:48:42 AM UTC-7, Trevor wrote: This has turned into a bit of an interesting adventure in the syntax of Tidy. Environment: puppet 0.24.8 on Fedora Core 11 After each run, I touch /tmp/foodir/bar to have something to tidy. Test code: # Environment Setup $testdir = /tmp/foodir $subdir = $testdir/subdir file { $testdir: ensure = 'directory', require = Tidy[$testdir] } file { $subdir: ensure = 'directory' } file { $subdir/foo: ensure = 'file', content = foo } file { $testdir/foolink: ensure = $subdir/foo } Test 1: tidy { $testdir: age = '0s', matches = * } Test 1 Result: Fail, bar remains Test 2: tidy { $testdir: age = '0s', matches = .* } Test 2 Result: Fail, bar remains Test 3: tidy { $testdir: age = '0s', recurse = 'true' } Test 3 Result: Pass, bar deleted Test 4: Created a symlink /tmp/foodir/baz that points to /tmp/foodir/subdir/foo tidy { $testdir: age = '0s', recurse = 'true' } Test 4 Result: Partial, bar deleted, baz remains Test 5: Created the symlink baz and touched bar tidy { $testdir: age = '0s', recurse = 'true', type = 'mtime' } Test 5 Result: Pass Comments: I don't quite understand why the pass/fail combinations work above. I also noticed that any subdirectory that is explicitly managed will not be recursed into even if recurse is set to 'true'. I believe that it should recurse through all subdirectories, not just the ones that aren't otherwise managed. Thanks, Trevor On Fri, Jul 24, 2009 at 00:21, Greggreg...@gmail.com javascript: wrote: Trevor, Not sure - the docs don't seem to reference symlinks in terms of tidy... Just something to try - does setting rmdirs = true make any difference? Greg On Jul 24, 11:19 am, Trevor Vaughan peiriann...@gmail.com wrote: So, I have a directory of symlinks that I'm managing and Tidy doesn't seem to be doing much for me in there. Does Tidy ignore symlinks for some reason? If not, does anyone have the correct syntax? Thanks, Trevor -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/7de37acf-5daa-48af-a3d0-e6341bf4aa36%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.