Re: [Puppet Users] Custom type and provider development
On Thu, Mar 7, 2013 at 6:42 PM, Nan Liu nan@gmail.com wrote: On Thu, Mar 7, 2013 at 1:38 PM, Nan Liu nan@gmail.com wrote: On Thu, Mar 7, 2013 at 8:47 AM, damian.folw...@gmail.com wrote: Hi, I'm very new to Ruby, and pretty new to Puppet so apologies if this is a bit Puppet custom type development 101. We currently have a whole bunch of Windows services that are written in .Net. They are really simple and so we don't bother creating MSI installs for them and just use InstallUtil.exe called from a script. I'm looking at creating a simple Puppet type and provider that will allow me to install the service (via InstallUtil) if it doesn't already exist (as opposed to using an exec resource in which it is hard to determine if the service exists as a conditional). Now, there are many different flavours of .Net in use, and some are 32bit, some 64 bit. This means that I need to be able to specify what version of installutil.exe to use. Currently the type has a bunch of parameters (not properties) to specify this. E.g. dotnetwinservice {'MyService': ensure= present, dotnetversion = '4.0.30319', sixtyfourbit = false, path = 'c:\program files(x86)\myapp\myapp.exe', } My question is, in the provider code what is the best way to dynamically determine the installutil path? All of the examples i can find setting a command are not dynamic (i.e. the full command path is known without looking at parameter values). My provider code looks like the below... The INSTALLUTIL value is currently hard coded. I'd like to do something like the commented out code but it doesn't appear as though either @property_hash or @resource have values at the time of execution (I get undefined method [] for nil:nilClass error). Puppet::Type.type(:dotnetwinservice).provide(:dotnetwinservice) do desc DotNet Windows Service confine :operatingsystem = :windows defaultfor :operatingsystem = :windows #dotnetframeworkversion = @resource[:sixtyfourbit] ? 'Framework64' : 'Framework' #installutilpath = #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\#{@resource[:dotnetversion]}\\InstallUtil.exe #INSTALLUTIL = # if File.exists?(installutilpath) #installutilpath # else #raise Puppet::Error.new(Cannot find installutil.exe for dotnetversion #{@property_hash[:dotnetversion]} at #{installutilpath} ) # end INSTALLUTIL = #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\v4.0.30319\\InstallUtil.exe commands :installutil = INSTALLUTIL def create installutil(/unattended, @resource[:path]) end def destroy installutil(/u, /unattended, @resource[:path]) end def exists? Win32::Service.exists?( @resource[:name] ) end end See example here, you should be able to do something similar: https://github.com/puppetlabs/puppetlabs-dism/blob/master/lib/puppet/provider/dism/dism.rb#L7-L13 Rethinking a bit more since you need access to a provider parameter, you may need to do something closer to this: commands :default_installutil = INSTALLUTIL def installutil(*args) if @resource[:dotnetversion] args.unshift #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\#{@ resource[:dotnetversion]}\\InstallUtil.exe Puppet.debug(Executing '#{args.inspect}') execute(args, :failonfail = true) else default_installutil *args end end def create installutil(/unattended, @resource[:path]) end 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 post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out. Some background on why this is necessary. When you declare: Puppet::Type.type(:dotnetwinservice).provide(:dotnetwinservice) Puppet uses metaprogramming to define a new class named Puppet::Type::Dotnetwinservice::ProviderDotnetwinservice, and it adds instance methods to the class, e.g. `def create`. Within the body of an instance method, you have access to instance variables, e.g. @resource, and methods, e.g. Puppet::Provider#set, #get, #resource, etc. However, statements that are not within an instance method such as: dotnetframeworkversion = @resource[:sixtyfourbit] ? 'Framework64' : 'Framework' are being evaluated in the context of your class, not an instance of your class. So you don't have access to instance variables like @resource, and that's why you need to create a helper method like Nan suggested. Unfortunately, you as a provider author have to know in which context your code is being evaluated, as that will determine what methods and variables you have access to. HTH, Josh -- Josh Cooper Developer,
Re: [Puppet Users] Custom type and provider development
Thanks Nan and Josh. Your help is much appreciated. Once I've finished first draft I'll upload to GitHub / Forge and ask for comments! -- 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 post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
[Puppet Users] Custom type and provider development
Hi, I'm very new to Ruby, and pretty new to Puppet so apologies if this is a bit Puppet custom type development 101. We currently have a whole bunch of Windows services that are written in .Net. They are really simple and so we don't bother creating MSI installs for them and just use InstallUtil.exe called from a script. I'm looking at creating a simple Puppet type and provider that will allow me to install the service (via InstallUtil) if it doesn't already exist (as opposed to using an exec resource in which it is hard to determine if the service exists as a conditional). Now, there are many different flavours of .Net in use, and some are 32bit, some 64 bit. This means that I need to be able to specify what version of installutil.exe to use. Currently the type has a bunch of parameters (not properties) to specify this. E.g. dotnetwinservice {'MyService': ensure= present, dotnetversion = '4.0.30319', sixtyfourbit = false, path = 'c:\program files(x86)\myapp\myapp.exe', } My question is, in the provider code what is the best way to dynamically determine the installutil path? All of the examples i can find setting a command are not dynamic (i.e. the full command path is known without looking at parameter values). My provider code looks like the below... The INSTALLUTIL value is currently hard coded. I'd like to do something like the commented out code but it doesn't appear as though either @property_hash or @resource have values at the time of execution (I get undefined method [] for nil:nilClass error). Puppet::Type.type(:dotnetwinservice).provide(:dotnetwinservice) do desc DotNet Windows Service confine :operatingsystem = :windows defaultfor :operatingsystem = :windows #dotnetframeworkversion = @resource[:sixtyfourbit] ? 'Framework64' : 'Framework' #installutilpath = #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\#{@resource[:dotnetversion]}\\InstallUtil.exe #INSTALLUTIL = # if File.exists?(installutilpath) #installutilpath # else #raise Puppet::Error.new(Cannot find installutil.exe for dotnetversion #{@property_hash[:dotnetversion]} at #{installutilpath} ) # end INSTALLUTIL = #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\v4.0.30319\\InstallUtil.exe commands :installutil = INSTALLUTIL def create installutil(/unattended, @resource[:path]) end def destroy installutil(/u, /unattended, @resource[:path]) end def exists? Win32::Service.exists?( @resource[:name] ) end end -- 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 post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: [Puppet Users] Custom type and provider development
On 03/07/2013 05:47 PM, damian.folw...@gmail.com wrote: My question is, in the provider code what is the best way to dynamically determine the installutil path? All of the examples i can find setting a command are not dynamic (i.e. the full command path is known without looking at parameter values). Really interesting question... I don't know the answer but am looking forward to hearing :) Maybe Nan Liu can help? -- 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 post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: [Puppet Users] Custom type and provider development
On Thu, Mar 7, 2013 at 8:47 AM, damian.folw...@gmail.com wrote: Hi, I'm very new to Ruby, and pretty new to Puppet so apologies if this is a bit Puppet custom type development 101. We currently have a whole bunch of Windows services that are written in .Net. They are really simple and so we don't bother creating MSI installs for them and just use InstallUtil.exe called from a script. I'm looking at creating a simple Puppet type and provider that will allow me to install the service (via InstallUtil) if it doesn't already exist (as opposed to using an exec resource in which it is hard to determine if the service exists as a conditional). Now, there are many different flavours of .Net in use, and some are 32bit, some 64 bit. This means that I need to be able to specify what version of installutil.exe to use. Currently the type has a bunch of parameters (not properties) to specify this. E.g. dotnetwinservice {'MyService': ensure= present, dotnetversion = '4.0.30319', sixtyfourbit = false, path = 'c:\program files(x86)\myapp\myapp.exe', } My question is, in the provider code what is the best way to dynamically determine the installutil path? All of the examples i can find setting a command are not dynamic (i.e. the full command path is known without looking at parameter values). My provider code looks like the below... The INSTALLUTIL value is currently hard coded. I'd like to do something like the commented out code but it doesn't appear as though either @property_hash or @resource have values at the time of execution (I get undefined method [] for nil:nilClass error). Puppet::Type.type(:dotnetwinservice).provide(:dotnetwinservice) do desc DotNet Windows Service confine :operatingsystem = :windows defaultfor :operatingsystem = :windows #dotnetframeworkversion = @resource[:sixtyfourbit] ? 'Framework64' : 'Framework' #installutilpath = #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\#{@resource[:dotnetversion]}\\InstallUtil.exe #INSTALLUTIL = # if File.exists?(installutilpath) #installutilpath # else #raise Puppet::Error.new(Cannot find installutil.exe for dotnetversion #{@property_hash[:dotnetversion]} at #{installutilpath} ) # end INSTALLUTIL = #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\v4.0.30319\\InstallUtil.exe commands :installutil = INSTALLUTIL def create installutil(/unattended, @resource[:path]) end def destroy installutil(/u, /unattended, @resource[:path]) end def exists? Win32::Service.exists?( @resource[:name] ) end end See example here, you should be able to do something similar: https://github.com/puppetlabs/puppetlabs-dism/blob/master/lib/puppet/provider/dism/dism.rb#L7-L13 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 post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: [Puppet Users] Custom type and provider development
On Thu, Mar 7, 2013 at 1:38 PM, Nan Liu nan@gmail.com wrote: On Thu, Mar 7, 2013 at 8:47 AM, damian.folw...@gmail.com wrote: Hi, I'm very new to Ruby, and pretty new to Puppet so apologies if this is a bit Puppet custom type development 101. We currently have a whole bunch of Windows services that are written in .Net. They are really simple and so we don't bother creating MSI installs for them and just use InstallUtil.exe called from a script. I'm looking at creating a simple Puppet type and provider that will allow me to install the service (via InstallUtil) if it doesn't already exist (as opposed to using an exec resource in which it is hard to determine if the service exists as a conditional). Now, there are many different flavours of .Net in use, and some are 32bit, some 64 bit. This means that I need to be able to specify what version of installutil.exe to use. Currently the type has a bunch of parameters (not properties) to specify this. E.g. dotnetwinservice {'MyService': ensure= present, dotnetversion = '4.0.30319', sixtyfourbit = false, path = 'c:\program files(x86)\myapp\myapp.exe', } My question is, in the provider code what is the best way to dynamically determine the installutil path? All of the examples i can find setting a command are not dynamic (i.e. the full command path is known without looking at parameter values). My provider code looks like the below... The INSTALLUTIL value is currently hard coded. I'd like to do something like the commented out code but it doesn't appear as though either @property_hash or @resource have values at the time of execution (I get undefined method [] for nil:nilClass error). Puppet::Type.type(:dotnetwinservice).provide(:dotnetwinservice) do desc DotNet Windows Service confine :operatingsystem = :windows defaultfor :operatingsystem = :windows #dotnetframeworkversion = @resource[:sixtyfourbit] ? 'Framework64' : 'Framework' #installutilpath = #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\#{@resource[:dotnetversion]}\\InstallUtil.exe #INSTALLUTIL = # if File.exists?(installutilpath) #installutilpath # else #raise Puppet::Error.new(Cannot find installutil.exe for dotnetversion #{@property_hash[:dotnetversion]} at #{installutilpath} ) # end INSTALLUTIL = #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\v4.0.30319\\InstallUtil.exe commands :installutil = INSTALLUTIL def create installutil(/unattended, @resource[:path]) end def destroy installutil(/u, /unattended, @resource[:path]) end def exists? Win32::Service.exists?( @resource[:name] ) end end See example here, you should be able to do something similar: https://github.com/puppetlabs/puppetlabs-dism/blob/master/lib/puppet/provider/dism/dism.rb#L7-L13 Rethinking a bit more since you need access to a provider parameter, you may need to do something closer to this: commands :default_installutil = INSTALLUTIL def installutil(*args) if @resource[:dotnetversion] args.unshift #{ENV['SYSTEMROOT']}\\Microsoft.NET\\Framework\\#{@ resource[:dotnetversion]}\\InstallUtil.exe Puppet.debug(Executing '#{args.inspect}') execute(args, :failonfail = true) else default_installutil *args end end def create installutil(/unattended, @resource[:path]) end 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 post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.