Hi, Is it possible to have an array as the output of a custom fact? And then to pass it into a template in Puppet? I currently have a fact that looks like this: Facter.add("exports") do setcode do case Facter.hostname when (/thishost/i): [ "/local", "/local2" ] end end end & a template like this: <% exports.each do |exp| -%> <%= exp %> 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) <% end -%> When I test the fact locally, the output is exports: /local/local2 (although ''facter exports'' gives /local and /local2 on separate lines). When Puppet runs and uses the template, the line output is /local/local2 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) rather than /local 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) /local2 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) which is what I''m after. I''m using 0.20.1 (from Debian etch). Am I doing something wrong, or is this not possible? If the latter - any suggestions as to alternative ways of managing this? Juliet -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Ms Juliet Kemp + + Computer Manager star@imperial.ac.uk + + Astrophysics Group + + Imperial College Tel: +44 (0)20759 47538 + + London. SW7 2AZ Fax: +44 (0)20759 47541 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
On Nov 13, 2007, at 10:23 AM, Juliet Kemp wrote:> I''m using 0.20.1 (from Debian etch). Am I doing something wrong, > or is > this not possible? If the latter - any suggestions as to alternative > ways of managing this?It''s not currently possible, but if you remodel these as resources that generate your exports file you should be able to avoid the need for arrays. E.g., something like: export { "/local", "/local2": options => "155.198.204.0/255.255.255.0 (rw,sync,no_root_squash)", ensure => present } -- Never esteem anything as of advantage to you that will make you break your word or lose your self-respect. -- Marcus Aurelius Antoninus --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
On Tue, Nov 13, 2007 at 04:23:25PM +0000, Juliet Kemp wrote:> Is it possible to have an array as the output of a custom fact? And > then to pass it into a template in Puppet? > > I currently have a fact that looks like this: > > Facter.add("exports") do > setcode do > case Facter.hostname > when (/thishost/i): > [ "/local", "/local2" ] > end > end > endIs that *really* what your fact looks like, or is it a sample for the purposes of illustrating the question? If you''re really using Facter to set variables like this, I''d suggest you go and learn about defines and the wonderous splendour they can impart to your manifests. You really shouldn''t be (ab)using facts for this purpose. To answer the larger question, no, you can''t reliably supply arrays in facts. There''s lots of calls to to_s in the facter code, and while I can''t identify which one will specifically do you in, there''s enough of them in there in strategic places to cause guaranteed confusion. On top of that, there''s also Puppet''s handling of facts, which is a whole other world...> When I test the fact locally, the output is > > exports: /local/local2Which is [''/local'', ''/local2''].to_s (since to_s on an array is just a shorthand form of .join('''')).> (although ''facter exports'' gives /local and /local2 on separate lines).That would be because puts has some special array-handling magic in it, so that when you puts an array it''ll print it out on separate lines.> When Puppet runs and uses the template, the line output is > > /local/local2 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) > > rather than > > /local 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) > /local2 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) > > which is what I''m after.Although the fact still seems to be an array at the end of Facter time, Puppet will certainly convert it to a string before it ever gets near your manifest.> I''m using 0.20.1 (from Debian etch). Am I doing something wrong, or is > this not possible? If the latter - any suggestions as to alternative > ways of managing this?You could (should!) give 0.23.2 a go, but I''m confident it won''t solve this particular problem you''re having. - Matt -- That''s why I love VoIP. You don''t get people phoning up to complain that the network is down. -- Peter Corlett, in the Monastery
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Tuesday 13 November 2007, Juliet Kemp wrote:> Hi, > > Is it possible to have an array as the output of a custom fact? And > then to pass it into a template in Puppet? > > I currently have a fact that looks like this: > > Facter.add("exports") do > setcode do > case Facter.hostname > when (/thishost/i): > [ "/local", "/local2" ] > end > end > end > > & a template like this: > > <% exports.each do |exp| -%> > <%= exp %> 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) > <% end -%> > > When I test the fact locally, the output is > > exports: /local/local2 > > (although ''facter exports'' gives /local and /local2 on separate lines). > > When Puppet runs and uses the template, the line output is > > /local/local2 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) > > rather than > > /local 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) > /local2 155.198.204.0/255.255.255.0(rw,sync,no_root_squash) > > which is what I''m after. > > I''m using 0.20.1 (from Debian etch). Am I doing something wrong, or is > this not possible? If the latter - any suggestions as to alternative > ways of managing this?You can take a look at my NTP module[1] where I use a custom fact and function to pass arrays around. Be aware though that while this is production code configuring my NTP subnet, I wouldn''t call it exactly "Best Practise". [1] http://reductivelabs.com/trac/puppet/wiki/CompleteConfiguration Regards, David - -- The primary freedom of open source is not the freedom from cost, but the free- dom to shape software to do what you want. This freedom is /never/ exercised without cost, but is available /at all/ only by accepting the very different costs associated with open source, costs not in money, but in time and effort. - -- http://www.schierer.org/~luke/log/20070710-1129/on-forks-and-forking -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFHOu3e/Pp1N6Uzh0URAruIAJ9OUQ+VHr0k4lfswjbtOqe4J5HzbQCbBjqe 8uGEYlYYH0qMd2IJePOWW08=okCx -----END PGP SIGNATURE-----
Luke Kanies wrote:> On Nov 13, 2007, at 10:23 AM, Juliet Kemp wrote: > >> I''m using 0.20.1 (from Debian etch). Am I doing something wrong, >> or is >> this not possible? If the latter - any suggestions as to alternative >> ways of managing this? > > It''s not currently possible, but if you remodel these as resources > that generate your exports file you should be able to avoid the need > for arrays. E.g., something like: > > export { "/local", "/local2": options => "155.198.204.0/255.255.255.0 > (rw,sync,no_root_squash)", ensure => present }Thanks. The trouble with this approach - and with Matt''s suggestion of using defines - is that it is pretty untidy in terms of node classes. I have about 50 machines, which have between them maybe 10 different sets of NFS-exported directories (some have just /local, some /local, /local2, some /local, /data1, /data2, etc etc). I also use LDAP for class storage for my nodes. So my previous setup was to create an "export" definition, and then have the appropriate number of export_directory classes. Then each node had as an LDAP attribute puppetclass: export_relevant_directory_class Which worked, but it meant that I had a large collection of export_directory classes, which seemed a bit untidy. Redefining it as a fact seemed (to me, anyway!) to be a neater way of dealing with it. (For a definition of "neat" which means that my directory of node classes is easier to deal with; the fact itself was a bit icky.) I guess another option would be to set an array by hostname within the export class/definition; although that seems unwieldy as well. Any other suggestions? Juliet -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Ms Juliet Kemp + + Computer Manager star@imperial.ac.uk + + Astrophysics Group + + Imperial College Tel: +44 (0)20759 47538 + + London. SW7 2AZ Fax: +44 (0)20759 47541 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
On Thu, Nov 15, 2007 at 09:56:21AM +0000, Juliet Kemp wrote:> Luke Kanies wrote: > > On Nov 13, 2007, at 10:23 AM, Juliet Kemp wrote: > > > >> I''m using 0.20.1 (from Debian etch). Am I doing something wrong, > >> or is > >> this not possible? If the latter - any suggestions as to alternative > >> ways of managing this? > > > > It''s not currently possible, but if you remodel these as resources > > that generate your exports file you should be able to avoid the need > > for arrays. E.g., something like: > > > > export { "/local", "/local2": options => "155.198.204.0/255.255.255.0 > > (rw,sync,no_root_squash)", ensure => present } > > The trouble with this approach - and with Matt''s suggestion of using > defines - is that it is pretty untidy in terms of node classes. > > I have about 50 machines, which have between them maybe 10 different > sets of NFS-exported directories (some have just /local, some /local, > /local2, some /local, /data1, /data2, etc etc). I also use LDAP for > class storage for my nodes.[...]> Any other suggestions?Fix the external nodes stuff so it handles defined types properly? It seems to me to be a *major* failing of the external nodes classifier that it can only deal with classes. If I ever decide to use an external node classifier, I''ll be fixing it so that defines work -- after all, what is it other than a class with parameters? It doesn''t seem like it''d be hard to represent that extra data in YAML. However, editing manifests/nodes/<site>.pp works fine for me, so it''ll be up to someone else to fix it for the foreseeable future. Hmm, actually, I wonder if an external node classifier that wrote a manifest full of nodes, with all the relevant defines, would do the job? <grin> - Matt -- A byte walks into a bar and orders a pint. Bartender asks him "What''s wrong?" The byte says "Parity error." Bartender nods and says "Yeah, I thought you looked a bit off."
On 11/15/07, Juliet Kemp <j.kemp@imperial.ac.uk> wrote:> Thanks. > > The trouble with this approach - and with Matt''s suggestion of using > defines - is that it is pretty untidy in terms of node classes. > > I have about 50 machines, which have between them maybe 10 different > sets of NFS-exported directories (some have just /local, some /local, > /local2, some /local, /data1, /data2, etc etc). I also use LDAP for > class storage for my nodes. > > So my previous setup was to create an "export" definition, and then have > the appropriate number of export_directory classes. Then each node had > as an LDAP attribute > > puppetclass: export_relevant_directory_class > > Which worked, but it meant that I had a large collection of > export_directory classes, which seemed a bit untidy. Redefining it as a > fact seemed (to me, anyway!) to be a neater way of dealing with it. > (For a definition of "neat" which means that my directory of node > classes is easier to deal with; the fact itself was a bit icky.) > > I guess another option would be to set an array by hostname within the > export class/definition; although that seems unwieldy as well. > > Any other suggestions?iClassify can help you solve this problem, although I think it''s still got a bit more cooking to do before it''s ready for widespread use (another week or so and I should have some tutorials ready.) The way this would work in iClassify would be to add an icagent recipe (much like a Factor fact, but put into the external node classification tool instead) that dynamically configures the attribute for you. Something like: case attrib?("hostname") when /something/ add_attrib("exports", [ "/local1", "/data1" ] ) end Would do it. This would then be available in your node definitions dynamically. Here is a sample of what the final YAML returned by icpuppet would be: --- parameters: exports: - /local1 - /data1 processorcount: "2" kernel: Linux innodb_buffer_pool_size: 25M uniqueid: f948840c rubysitedir: /usr/local/lib/site_ruby/1.8 operatingsystemrelease: 2.6.18-xenU hardwaremodel: x86_64 swapfree: 127.98 MB puppet_env: prod memorysize: "950.20" ps: ps -ef kernelrelease: 2.6.18-xenU hardwareisa: unknown apache_listen_ports: - "80" - "443" lsbdistdescription: Ubuntu 7.04 lsbdistid: Ubuntu classes: - operations-master - your-class-here Regards, Adam -- HJK Solutions - We Launch Startups - http://www.hjksolutions.com Adam Jacob, Senior Partner T: (206) 508-4759 E: adam@hjksolutions.com