summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/package/pkg.rb
blob: 148ef0d62228d060639a32fa176c7de05d5f276e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
require 'puppet/provider/package'

Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package do
    desc "OpenSolaris image packaging system. See pkg(5) for more information"

    commands :pkg => "/usr/bin/pkg"

    confine :operatingsystem => :solaris

    #defaultfor [:operatingsystem => :solaris, :kernelrelease => "5.11"]

    def self.instances
        packages = []

        cmd = "#{command(:pkg)} list -H"
        execpipe(cmd) do |process|
            hash = {}

            # now turn each returned line into a package object
            process.each { |line|
                if hash = parse_line(line)
                    packages << new(hash)
                end
            }
        end

        packages
    end

    self::REGEX = %r{^(\S+)\s+(\S+)\s+(\S+)\s+}
    self::FIELDS = [:name, :version, :status]

    def self.parse_line(line)
        hash = {}
        if match = self::REGEX.match(line)

            self::FIELDS.zip(match.captures) { |field,value|
                hash[field] = value
            }

            hash[:provider] = self.name
            hash[:error] = "ok"

            if hash[:status] == "installed"
                hash[:ensure] = :present
            else
                hash[:ensure] = :absent
            end
        else
            Puppet.warning "Failed to match 'pkg list' line %s" % line.inspect
            return nil
        end

        return hash
    end

    # return the version of the package
    # TODO deal with multiple publishers
    def latest
        version = nil
        pkg(:list, "-Ha", @resource[:name]).split("\n").each do |line|
            v = line.split[2]
            case v
            when "known"
                return v
            when "installed"
                version = v
            else
                Puppet.warn "unknown package state for %s: %s" %
                            [@resource[:name], v]
            end
        end
        version
    end

    # install the package
    def install
        pkg :install, @resource[:name]
    end

    # uninstall the package
    def uninstall
        pkg :uninstall, '-r', @resource[:name]
    end

    # update the package to the latest version available
    def update
        self.install
    end

    # list a specific package
    def query
        begin
            output = pkg(:list, "-H", @resource[:name])
        rescue Puppet::ExecutionFailure
            # pkg returns 1 if the package is not found.
            return {:ensure => :absent, :status => 'missing',
                    :name => @resource[:name], :error => 'ok'}
        end

        hash = self.class.parse_line(output) || 
               {:ensure => :absent, :status => 'missing',
                :name => @resource[:name], :error => 'ok'}

        if hash[:error] != "ok"
              raise Puppet::Error.new(
                    "Package %s, version %s is in error state: %s" %
                    [hash[:name], hash[:version], hash[:error]])
        end

        return hash
    end

end