Hi! I am soooo close to getting my vncserver type to work; I have one last hurdle. There are two kinds of record lines in a vncserver config file, so I have two record_line definitions in my provider. Only one of them gets called, though! The one that has the same name, ":parsed", as what I pass to provide . . . require ''puppet/provider/parsedfile'' vncservers = "/etc/sysconfig/vncservers" Puppet::Type.type(:vncserver).provide(:parsed, :parent => Puppet::Provider::ParsedFile, :filetype => :flat, :default_target => vncservers ) do desc "The vncserver provider that uses the ParsedFile class" confine :exists => vncservers text_line :comment, :match => /^\s*#/; text_line :blank, :match => /^\s*$/; record_line :parsed_opts, :fields => %w{name pre_geo_opts geometry post_geo_opts}, :optional => %w{pre_geo_opts post_geo_opts}, :match => /^VNCSERVERARGS\[(\d+)\]="(.*)\s*-geometry (\d+x\d+)(.*)"$/, :to_line => proc { |record| # Should end up looking like: # VNCSERVERARGS[92]="-geometry 1280x1024" ''VNCSERVERARGS['' + record[:name] + '']="-geometry '' + record[:geometry] + ''"'' }; record_line :parsed_portuser, :fields => %w{name username}, :match => /^VNCSERVERS="\$VNCSERVERS\s+(\d+):(\w+)\s*"$/, :to_line => proc { |record| # Should end up looking like: # VNCSERVERS="$VNCSERVERS 2:firstuser" ''VNCSERVERS="$VNCSERVERS '' + record[:name] + '':'' + record[:username] + ''"'' }; end Thanks a lot!! Guy -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Stefan Schulte
2011-Nov-09 19:38 UTC
Re: [Puppet Users] so close to getting new type to work!!
On Wed, Nov 09, 2011 at 01:08:37PM -0500, Guy Matz wrote:> Hi! I am soooo close to getting my vncserver type to work; I have one last > hurdle. There are two kinds of record lines in a vncserver config file, so > I have two record_line definitions in my provider. Only one of them gets > called, though! The one that has the same name, ":parsed", as what I pass > to provide . . . > > require ''puppet/provider/parsedfile'' > > vncservers = "/etc/sysconfig/vncservers" > > Puppet::Type.type(:vncserver).provide(:parsed, > :parent => > Puppet::Provider::ParsedFile, > :filetype => :flat, > :default_target => vncservers > ) do > > desc "The vncserver provider that uses the ParsedFile class" > > confine :exists => vncservers > > text_line :comment, :match => /^\s*#/; > text_line :blank, :match => /^\s*$/; > > record_line :parsed_opts, > :fields => %w{name pre_geo_opts geometry post_geo_opts}, > :optional => %w{pre_geo_opts post_geo_opts}, > :match => /^VNCSERVERARGS\[(\d+)\]="(.*)\s*-geometry > (\d+x\d+)(.*)"$/, > :to_line => proc { |record| > # Should end up looking like: > # VNCSERVERARGS[92]="-geometry 1280x1024" > ''VNCSERVERARGS['' + record[:name] + > '']="-geometry '' + record[:geometry] + ''"'' > }; > record_line :parsed_portuser, > :fields => %w{name username}, > :match => /^VNCSERVERS="\$VNCSERVERS\s+(\d+):(\w+)\s*"$/, > :to_line => proc { |record| > # Should end up looking like: > # VNCSERVERS="$VNCSERVERS 2:firstuser" > ''VNCSERVERS="$VNCSERVERS '' + > record[:name] + '':'' + record[:username] + ''"'' > }; > end > > > Thanks a lot!! > > GuyTo be clear here can you have something like VNCSERVERARGS[23]=... VNCSERVERS="$VNCSERVERS 23:user" Because after parsing the whole file, puppet will have two records with record[:name] = 23 but the contents are not merged. So when prefetching happens and you have a resource type with the name 23, the resource will get a provider with pre_geo_opts, geometry and post_geo_opts OR a provider with username set but never both. -Stefan
Stefan, Right! I think. With a resource that looks like : vncserver { ''92'': username => ''athusr'', geometry => ''123x78'', ensure => ''present''; } I should get two entries in /etc/sysconfig/vncserver: VNCSERVERARGS[92]="-geometry 123x78" VNCSERVERS="$VNCSERVERS 92:athusr" I''m sorry if I am not understanding your post, and responding to it nonsensically. Are you saying that with a single "name" of 92, I will not be able to make changes on two lines? Thanks a lot! Guy On Wed, Nov 9, 2011 at 2:38 PM, Stefan Schulte < stefan.schulte@taunusstein.net> wrote:> On Wed, Nov 09, 2011 at 01:08:37PM -0500, Guy Matz wrote: > > Hi! I am soooo close to getting my vncserver type to work; I have one > last > > hurdle. There are two kinds of record lines in a vncserver config file, > so > > I have two record_line definitions in my provider. Only one of them gets > > called, though! The one that has the same name, ":parsed", as what I > pass > > to provide . . . > > > > require ''puppet/provider/parsedfile'' > > > > vncservers = "/etc/sysconfig/vncservers" > > > > Puppet::Type.type(:vncserver).provide(:parsed, > > :parent => > > Puppet::Provider::ParsedFile, > > :filetype => :flat, > > :default_target => vncservers > > ) do > > > > desc "The vncserver provider that uses the ParsedFile class" > > > > confine :exists => vncservers > > > > text_line :comment, :match => /^\s*#/; > > text_line :blank, :match => /^\s*$/; > > > > record_line :parsed_opts, > > :fields => %w{name pre_geo_opts geometry post_geo_opts}, > > :optional => %w{pre_geo_opts post_geo_opts}, > > :match => /^VNCSERVERARGS\[(\d+)\]="(.*)\s*-geometry > > (\d+x\d+)(.*)"$/, > > :to_line => proc { |record| > > # Should end up looking like: > > # VNCSERVERARGS[92]="-geometry 1280x1024" > > ''VNCSERVERARGS['' + record[:name] + > > '']="-geometry '' + record[:geometry] + ''"'' > > }; > > record_line :parsed_portuser, > > :fields => %w{name username}, > > :match => /^VNCSERVERS="\$VNCSERVERS\s+(\d+):(\w+)\s*"$/, > > :to_line => proc { |record| > > # Should end up looking like: > > # VNCSERVERS="$VNCSERVERS 2:firstuser" > > ''VNCSERVERS="$VNCSERVERS '' + > > record[:name] + '':'' + record[:username] + ''"'' > > }; > > end > > > > > > Thanks a lot!! > > > > Guy > > To be clear here can you have something like > > VNCSERVERARGS[23]=... > VNCSERVERS="$VNCSERVERS 23:user" > > Because after parsing the whole file, puppet will have two records with > record[:name] = 23 but the contents are not merged. > > So when prefetching happens and you have a resource type with the name 23, > the resource will get a provider with pre_geo_opts, geometry and > post_geo_opts OR a provider with username set but never both. > > -Stefan >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Stefan Schulte
2011-Nov-09 20:48 UTC
Re: [Puppet Users] so close to getting new type to work!!
On Wed, Nov 09, 2011 at 02:45:30PM -0500, Guy Matz wrote:> Stefan, > Right! I think. With a resource that looks like : > vncserver { ''92'': > username => ''athusr'', > geometry => ''123x78'', > ensure => ''present''; > } > > I should get two entries in /etc/sysconfig/vncserver: > VNCSERVERARGS[92]="-geometry 123x78" > VNCSERVERS="$VNCSERVERS 92:athusr" > > I''m sorry if I am not understanding your post, and responding to it > nonsensically. Are you saying that with a single "name" of 92, I will not > be able to make changes on two lines? >Yes. Every line in your config file (that is not a text line like a comment) will be parsed as one record. During prefetching puppet tries to match the resources the user has defined in his manifest with the records of your target file(s). It works like this Puppet iterates over every record. If puppet has a resource with a name that matches the current record''s name then puppet creates a provider instance and assignes the provider to this resource. So in short * each resource has zero or one prefetched provider * one provider corresponds to one specific record in your file Have a look at provider/parsedfile.rb method match_providers_with_resources You may be able to define a custom prefetch_hook method in your provider where you merge your different records into one. But I currently don''t know how puppet behaves when it has to rewrite the file after possible changes. Untested prefetch hook: def prefetch_hook(records) merged_records = {} # hash with the record''s name as key records.each do |record| if name = record[:name] merged_record[name] ||= {} merged_record[name].merge!(record) end end merged_records.values end You may get additional suggestions if you look at the cron provider. But in general I''m afraid that the parsedfile provider is not really good when information spanning over multiple lines. -Stefan> Thanks a lot! > Guy >
Fudge!! Thanks for the pointer, Stefan . . . Yeah, the lines in match_providers_with_resources that says: if resource = match(record, matchers) # Remove this resource from circulation so we don’t unnecessarily try to match matchers.delete(resource.title) . . . Means that it can never match two lines, I guess! Thanks again . . . On Wed, Nov 9, 2011 at 3:48 PM, Stefan Schulte < stefan.schulte@taunusstein.net> wrote:> On Wed, Nov 09, 2011 at 02:45:30PM -0500, Guy Matz wrote: > > Stefan, > > Right! I think. With a resource that looks like : > > vncserver { ''92'': > > username => ''athusr'', > > geometry => ''123x78'', > > ensure => ''present''; > > } > > > > I should get two entries in /etc/sysconfig/vncserver: > > VNCSERVERARGS[92]="-geometry 123x78" > > VNCSERVERS="$VNCSERVERS 92:athusr" > > > > I''m sorry if I am not understanding your post, and responding to it > > nonsensically. Are you saying that with a single "name" of 92, I will > not > > be able to make changes on two lines? > > > > Yes. Every line in your config file (that is not a text line like a > comment) will be parsed as one record. During prefetching puppet tries > to match the resources the user has defined in his manifest with the > records of your target file(s). > > It works like this > Puppet iterates over every record. If puppet has a resource with a name > that matches the current record''s name then puppet creates a provider > instance > and assignes the provider to this resource. > > So in short > * each resource has zero or one prefetched provider > * one provider corresponds to one specific record in your file > > Have a look at provider/parsedfile.rb method > match_providers_with_resources > > You may be able to define a custom prefetch_hook method in your > provider where you merge your different records into one. But I > currently don''t know how puppet behaves when it has to rewrite the file > after possible changes. > > Untested prefetch hook: > > def prefetch_hook(records) > merged_records = {} # hash with the record''s name as key > records.each do |record| > if name = record[:name] > merged_record[name] ||= {} > merged_record[name].merge!(record) > end > end > merged_records.values > end > > You may get additional suggestions if you look at the cron provider. > > But in general I''m afraid that the parsedfile provider is not really > good when information spanning over multiple lines. > > -Stefan > > > Thanks a lot! > > Guy > > >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.