summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/package/apt.rb
blob: 6fa70e56af62241e4b110e3548c119c4c288fae8 (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
131
132
133
134
135
136
137
138
Puppet::Type.type(:package).provide :apt, :parent => :dpkg do
    # Provide sorting functionality
    include Puppet::Util::Package

    desc "Package management via ``apt-get``."

    commands :aptget => "/usr/bin/apt-get"
    commands :aptcache => "/usr/bin/apt-cache"
    commands :preseed => "/usr/bin/debconf-set-selections"

    defaultfor :operatingsystem => :debian

    ENV['DEBIAN_FRONTEND'] = "noninteractive"

    # A derivative of DPKG; this is how most people actually manage
    # Debian boxes, and the only thing that differs is that it can
    # install packages from remote sites.

    def aptcmd(*args)
        aptget(*args)
    end

    def checkforcdrom
        unless defined? @@checkedforcdrom
            if FileTest.exists? "/etc/apt/sources.list"
                if File.read("/etc/apt/sources.list") =~ /^[^#]*cdrom:/
                    @@checkedforcdrom = true
                else
                    @@checkedforcdrom = false
                end
            else
                # This is basically a pathalogical case, but we'll just
                # ignore it
                @@checkedforcdrom = false
            end
        end

        if @@checkedforcdrom and @model[:allowcdrom] != :true
            raise Puppet::Error,
                "/etc/apt/sources.list contains a cdrom source; not installing.  Use 'allowcdrom' to override this failure."
        end
    end

    # Install a package using 'apt-get'.  This function needs to support
    # installing a specific version.
    def install
        if @model[:responsefile]
            self.run_preseed
        end
        should = @model.should(:ensure)

        checkforcdrom()

        str = @model[:name]
        case should
        when true, false, Symbol
            # pass
        else
            # Add the package version
            str += "=%s" % should
        end
        cmd = %w{-q -y}

        keep = ""
        if config = @model[:configfiles]
            case config
            when :keep
                cmd << "-o" << 'DPkg::Options::=--force-confold'
            when :replace
                cmd << "-o" << 'DPkg::Options::=--force-confnew'
            else
                raise Puppet::Error, "Invalid 'configfiles' value %s" % config
            end
        end

        cmd << :install << str
        
        aptcmd(cmd)
    end

    # What's the latest package version available?
    def latest
        output = aptcache :showpkg,  @model[:name]

        if output =~ /Versions:\s*\n((\n|.)+)^$/
            versions = $1
            available_versions = versions.split(/\n/).collect { |version|
                if version =~ /^([^\(]+)\(/
                    $1
                else
                    self.warning "Could not match version '%s'" % version
                    nil
                end
            }.reject { |vers| vers.nil? }.sort { |a,b|
                versioncmp(a,b)
            }

            if available_versions.length == 0
                self.debug "No latest version"
                if Puppet[:debug]
                    print output
                end
            end

            # Get the latest and greatest version number
            return available_versions.pop
        else
            self.err "Could not match string"
        end
    end

	#
	# preseeds answers to dpkg-set-selection from the "responsefile"
	#
    def run_preseed
        if response = @model[:responsefile] and FileTest.exists?(response)
            self.info("Preseeding %s to debconf-set-selections" % response)

            preseed response
        else 
            self.info "No responsefile specified or non existant, not preseeding anything"
        end
    end

    def update
        self.install
    end

    def uninstall
        aptcmd "-y", "-q", :remove, @model[:name]
    end

    def versionable?
        true
    end
end

# $Id$