summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/package/rpm.rb
blob: a31e4edf6459237fd27c3921fd19aea8f5fa7513 (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
require 'puppet/provider/package'
# RPM packaging.  Should work anywhere that has rpm installed.
Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Provider::Package do
    desc "RPM packaging support; should work anywhere with a working ``rpm``
        binary."

    # The query format by which we identify installed packages
    NVRFORMAT = "%{NAME}-%{VERSION}-%{RELEASE}"

    VERSIONSTRING = "%{VERSION}-%{RELEASE}"

    commands :rpm => "rpm"

    if command('rpm')
        confine :true => begin
                rpm('-ql', 'rpm')
           rescue Puppet::ExecutionFailure
               false
           else
               true
           end
    end

    def self.instances
        packages = []

        # list out all of the packages
        begin
            execpipe("#{command(:rpm)} -qa --nosignature --nodigest --qf '%{NAME} #{VERSIONSTRING}\n'") { |process|
                # our regex for matching dpkg output
                regex = %r{^(\S+)\s+(\S+)}
                fields = [:name, :ensure]

                # now turn each returned line into a package object
                process.each { |line|
                    if match = regex.match(line)
                        hash = {}
                        fields.zip(match.captures) { |field,value|
                            hash[field] = value
                        }
                        hash[:provider] = self.name
                        packages << new(hash)
                    else
                        raise "failed to match rpm line %s" % line
                    end
                }
            }
        rescue Puppet::ExecutionFailure
            raise Puppet::Error, "Failed to list packages"
        end

        return packages
    end

    # Find the fully versioned package name and the version alone. Returns
    # a hash with entries :instance => fully versioned package name, and 
    # :ensure => version-release
    def query
        cmd = ["-q", @resource[:name], "--nosignature", "--nodigest", "--qf", "#{NVRFORMAT} #{VERSIONSTRING}\n"]

        begin
            output = rpm(*cmd)
        rescue Puppet::ExecutionFailure
            return nil
        end

        regex = %r{^(\S+)\s+(\S+)}
        fields = [:instance, :ensure]
        attrs = {}
        if match = regex.match(output)
            fields.zip(match.captures) { |field,value|
                attrs[field] = value
            }
        else
            raise Puppet::DevError,
                "Failed to match rpm output '%s'" %
                output
        end

        @nvr = attrs[:instance]

        return attrs
    end

    # Here we just retrieve the version from the file specified in the source.
    def latest
        unless source = @resource[:source]
            @resource.fail "RPMs must specify a package source"
        end
        
        cmd = [command(:rpm), "-q", "--qf", "#{VERSIONSTRING}", "-p", "#{@resource[:source]}"]
        version = execfail(cmd, Puppet::Error)
        return version
    end

    def install
        source = nil
        unless source = @resource[:source]
            @resource.fail "RPMs must specify a package source"
        end
        # RPM gets pissy if you try to install an already 
        # installed package
        if @resource.should(:ensure) == @property_hash[:ensure] or
            @resource.should(:ensure) == :latest && @property_hash[:ensure] == latest
            return
        end

        flag = "-i"
        if @property_hash[:ensure] and @property_hash[:ensure] != :absent
            flag = "-U"
        end

        rpm flag, "--oldpackage", source
    end

    def uninstall
        rpm "-e", nvr
    end

    def update
        self.install
    end

    def nvr
        query unless @nvr
        @nvr
    end
end

# $Id$