summaryrefslogtreecommitdiffstats
path: root/resize/progress.ml
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-01-18 22:05:02 +0000
committerRichard W.M. Jones <rjones@redhat.com>2012-01-18 22:05:02 +0000
commit08840bab44c38d0c69b5780c57b2bf370c96d58c (patch)
treea09d90f385c268782bb79755e9e9f6e7c6b6d3cb /resize/progress.ml
parentd8a1389df35ddd5b6d9af86dc27c1978ea07348f (diff)
downloadlibguestfs-08840bab44c38d0c69b5780c57b2bf370c96d58c.tar.gz
libguestfs-08840bab44c38d0c69b5780c57b2bf370c96d58c.tar.xz
libguestfs-08840bab44c38d0c69b5780c57b2bf370c96d58c.zip
Tempus fugit.
Update all copyright dates to 2012.
Diffstat (limited to 'resize/progress.ml')
-rw-r--r--resize/progress.ml2
1 files changed, 1 insertions, 1 deletions
diff --git a/resize/progress.ml b/resize/progress.ml
index 0ae72a38..e4fd47e0 100644
--- a/resize/progress.ml
+++ b/resize/progress.ml
@@ -1,5 +1,5 @@
(* virt-resize
- * Copyright (C) 2010-2011 Red Hat Inc.
+ * Copyright (C) 2010-2012 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
n177' href='#n177'>177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
module Puppet
    newtype(:tidy, :parent => Puppet.type(:file)) do
        @doc = "Remove unwanted files based on specific criteria.  Multiple
            criteria are OR'd together, so a file that is too large but is not
            old enough will still get tidied."

        newparam(:path) do
            desc "The path to the file or directory to manage.  Must be fully
                qualified."
            isnamevar
        end

        newparam(:matches) do
            desc "One or more file glob patterns, which restrict the list of
                files to be tidied to those whose basenames match at least one
                of the patterns specified.  Multiple patterns can be specified
                using an array."
        end

        copyparam(Puppet.type(:file), :backup)
        
        newproperty(:ensure) do
            desc "An internal attribute used to determine which files should be removed."

            @nodoc = true
            
            TATTRS = [:age, :size]
            
            defaultto :anything # just so we always get this property

            def change_to_s(currentvalue, newvalue)
                start = "Tidying"
                if @out.include?(:age)
                    start += ", older than %s seconds" % @resource.should(:age)
                end
                if @out.include?(:size)
                    start += ", larger than %s bytes" % @resource.should(:size)
                end

                start
            end

            def insync?(is)
                if is.is_a?(Symbol)
                    if [:absent, :notidy].include?(is)
                        return true
                    else
                        return false
                    end
                else
                    @out = []
                    if @resource[:matches]
                        basename = File.basename(@resource[:path])
                        flags = File::FNM_DOTMATCH | File::FNM_PATHNAME
                        unless @resource[:matches].any? {|pattern| File.fnmatch(pattern, basename, flags) }
                            self.debug "No patterns specified match basename, skipping"
                            return true
                        end
                    end
                    TATTRS.each do |param|
                        if property = @resource.property(param)
                            self.debug "No is value for %s", [param] if is[property].nil?
                            unless property.insync?(is[property])
                                @out << param
                            end
                        end
                    end
                    
                    if @out.length > 0
                        return false
                    else
                        return true
                    end
                end
            end
            
            def retrieve
                stat = nil
                unless stat = @resource.stat
                    return { self => :absent}
                end
                
                if stat.ftype == "directory" and ! @resource[:rmdirs]
                    return {self => :notidy}
                end

                allprops = TATTRS.inject({}) { |prophash, param|
                    if property = @resource.property(param)
                        prophash[property] = property.assess(stat)
                    end
                    prophash
                }
                return { self => allprops } 
            end

            def sync
                file = @resource[:path]
                case File.lstat(file).ftype
                when "directory":
                    if @resource[:rmdirs]
                        subs = Dir.entries(@resource[:path]).reject { |d|
                            d == "." or d == ".."
                        }.length
                        if subs > 0
                            self.info "%s has %s children; not tidying" %
                                [@resource[:path], subs]
                            self.info Dir.entries(@resource[:path]).inspect
                        else
                            Dir.rmdir(@resource[:path])
                        end
                    else
                        self.debug "Not tidying directories"
                        return nil
                    end
                when "file":
                    @resource.handlebackup(file)
                    File.unlink(file)
                when "link":
                    File.unlink(file)
                else
                    self.fail "Cannot tidy files of type %s" %
                        File.lstat(file).ftype
                end

                return :file_tidied
            end
        end

        newproperty(:age) do
            desc "Tidy files whose age is equal to or greater than
                the specified time.  You can choose seconds, minutes,
                hours, days, or weeks by specifying the first letter of any
                of those words (e.g., '1w')."

            @@ageconvertors = {
                :s => 1,
                :m => 60
            }

            @@ageconvertors[:h] = @@ageconvertors[:m] * 60
            @@ageconvertors[:d] = @@ageconvertors[:h] * 24
            @@ageconvertors[:w] = @@ageconvertors[:d] * 7

            def assess(stat)
                type = nil
                if stat.ftype == "directory"
                    type = :mtime
                else
                    type = @resource[:type] || :atime
                end
                
                return stat.send(type).to_i
            end

            def convert(unit, multi)
                if num = @@ageconvertors[unit]
                    return num * multi
                else
                    self.fail "Invalid age unit '%s'" % unit
                end
            end

            def insync?(is)
                if (Time.now.to_i - is) > self.should
                    return false
                end

                true
            end

            munge do |age|
                unit = multi = nil
                case age
                when /^([0-9]+)(\w)\w*$/:
                    multi = Integer($1)
                    unit = $2.downcase.intern
                when /^([0-9]+)$/:
                    multi = Integer($1)
                    unit = :d
                else
                    self.fail "Invalid tidy age %s" % age
                end

                convert(unit, multi)
            end
        end

        newproperty(:size) do
            desc "Tidy files whose size is equal to or greater than
                the specified size.  Unqualified values are in kilobytes, but
                *b*, *k*, and *m* can be appended to specify *bytes*, *kilobytes*,
                and *megabytes*, respectively.  Only the first character is
                significant, so the full word can also be used."

            @@sizeconvertors = {
                :b => 0,
                :k => 1,
                :m => 2,
                :g => 3
            }

            # Retrieve the size from a File::Stat object
            def assess(stat)
                return stat.size
            end

            def convert(unit, multi)
                if num = @@sizeconvertors[unit]
                    result = multi
                    num.times do result *= 1024 end
                    return result
                else
                    self.fail "Invalid size unit '%s'" % unit
                end
            end
            
            def insync?(is)
                if is > self.should
                    return false
                end

                true
            end
            
            munge do |size|
                case size
                when /^([0-9]+)(\w)\w*$/:
                    multi = Integer($1)
                    unit = $2.downcase.intern
                when /^([0-9]+)$/:
                    multi = Integer($1)
                    unit = :k
                else
                    self.fail "Invalid tidy size %s" % age
                end

                convert(unit, multi)
            end
        end

        newparam(:type) do
            desc "Set the mechanism for determining age."
            
            newvalues(:atime, :mtime, :ctime)

            defaultto :atime
        end

        newparam(:recurse) do
            desc "If target is a directory, recursively descend
                into the directory looking for files to tidy."
        end

        newparam(:rmdirs) do
            desc "Tidy directories in addition to files; that is, remove
                directories whose age is older than the specified criteria.
                This will only remove empty directories, so all contained
                files must also be tidied before a directory gets removed."
        end
        
        # Erase PFile's validate method
        validate do
        end

        def self.instances
            []
        end

        @depthfirst = true

        def initialize(hash)
            super

            unless  @parameters.include?(:age) or
                    @parameters.include?(:size)
                unless FileTest.directory?(self[:path])
                    # don't do size comparisons for directories
                    self.fail "Tidy must specify size, age, or both"
                end
            end

            # only allow backing up into filebuckets
            unless self[:backup].is_a? Puppet::Network::Client.dipper
                self[:backup] = false
            end
        end
        
        def retrieve
            # Our ensure property knows how to retrieve everything for us.
            if obj = @parameters[:ensure] 
                return obj.retrieve
            else
                return {}
            end
        end
        
        # Hack things a bit so we only ever check the ensure property.
        def properties
            []
        end
    end
end