Ask Your Question
0

Cannot figure out how to write custom type. [closed]

asked 2017-04-29 02:36:30 -0500

Red Cricket gravatar image

updated 2017-04-29 02:40:10 -0500

I am trying to teach myself how to write Puppet custom types. I have looked at this documentation: https://docs.puppet.com/puppet/4.10/customtypes.html and https://docs.puppet.com/puppet/4.10/providerdevelopment.html

Here is my contrived attempt to create a custom type that simple takes an array of strings and writes them to the file '/tmp/track-titles.txt'.

Here is my type code (modules/hello_world/lib/puppet/type/track_titles.rb):

Puppet::Type.newtype(:track_titles) do
  @doc = "Create track title file."

  ensurable

  newparam(:name) do
    desc "Mandaorty paramteter name ."
  end
  newparam(:track_titles) do
    desc "an arrary of strings"
  end

end

Here is my provider code: (modules/hello_world/lib/puppet/provider/track_titles.rb)

Puppet::Type.type(:track_titles).provide(:ruby) do
    desc "contrived example."

    def create
        track_titles.each do |title|
            system ( "echo #{title} >> @resource[:name]" )
        end
    end

    def destroy
        File.unlink(@resource[:name])
    end

    def exists?
        File.exists?(@resource[:name]))
    end
end

Here is my puppet module that uses the above: (modules/hello_world/manifests/init.pp)

class hello_world (
        $msg = 'Hello World',
        $track_titles = ['one','two','three'],
) {
#       notify { $msg: }
        track_titles { '/tmp/track-titles.txt':
                track_titles => $track_titles,
        }
}

I execute this code like so:

$ puppet apply \
> --modulepath=/home/red/PUPPET/modules \
> --hiera_config=/home/red/PUPPET/hiera.yaml \
> -e 'include hello_world'

And this is the output I get:

Notice: Compiled catalog for localhost in environment production in 0.06 seconds
Error: /Stage[main]/Hello_world/Track_titles[/tmp/track-titles.txt]: Could not evaluate: No ability to determine if track_titles exists
Notice: Finished catalog run in 0.82 seconds

What am I doing wrong. Also there are part of the provider code I don't get like:

Puppet::Type.type(:track_titles).provide(:ruby) do

What is this .provide(:ruby) all about?

Please help :)

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by WhatsARanjit
close date 2017-05-03 23:19:33.735434

1 Answer

Sort by ยป oldest newest most voted
0

answered 2017-04-29 23:54:58 -0500

Red Cricket gravatar image

OK. Here what I was doing wrong. For one I didn't read the documentation (https://docs.puppet.com/puppet/4.10/c...) close enough. It says:

Provider files should be located at lib/puppet/provider/<TYPE NAME>/<PROVIDER NAME>.rb

Knowing this helped figure out what the .provide(:thing) meant. :thing and <PROVIDER NAME> are the same thing and need to match. So here is my updated working code:

Here is the Puppet class:

$ cat modules/hello_world/manifests/init.pp
class hello_world (
        $track_titles = ['one','two','three'],
) {
        track_titles { '/tmp/track-titles.txt':
                tracks => $track_titles,
                ensure => present,
        }
}

Here is the Type definition:

$ cat modules/hello_world/lib/puppet/type/track_titles.rb
# blah blah blah
Puppet::Type.newtype(:track_titles) do
  @doc = "Create track title file."

  ensurable

  newparam(:name) do
    desc "Mandaorty paramteter name ."
  end
  newparam(:tracks) do
    desc "an arrary of strings"
  end
end

Here is the provider code. This was the code I was putting the file in the WRONG directory and that is why I was getting the Could not evaluate: No ability to determine if track_titles exists error.

$ cat modules/hello_world/lib/puppet/provider/track_titles/track_titles.rb
Puppet::Type.type(:track_titles).provide(:track_titles) do
    desc "Contrived example"

    def create
        filename = @resource[:name]
        tracks = @resource[:tracks]
        tracks.each do |t|
            system ( "echo #{t} >> #{filename}" )
        end
    end

    def destroy
        File.unlink(@resource[:name])
    end

    def exists?
        File.exists?(@resource[:name])
    end
end

Now here is a successful execution:

$ puppet apply \
> --modulepath=/home/red/PUPPET/modules \
> --hiera_config=/home/red/PUPPET/hiera.yaml \
> -e 'include hello_world'

Notice: Compiled catalog for localhost in environment production in 0.07 seconds
Notice: /Stage[main]/Hello_world/Track_titles[/tmp/track-titles.txt]/ensure: created
Notice: Finished catalog run in 0.85 seconds

$ cat /tmp/track-titles.txt
one
two
three
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-04-29 02:36:30 -0500

Seen: 41 times

Last updated: Apr 29