File ctime and mtime are now implemented as read-only properties, so
they can be examined with audit.

Signed-off-by: Jesse Wolfe <[email protected]>
---
 lib/puppet/type/file.rb       |    2 +
 lib/puppet/type/file/ctime.rb |   18 ++++++++++++++++
 lib/puppet/type/file/mtime.rb |   17 +++++++++++++++
 spec/unit/type/file/ctime.rb  |   44 +++++++++++++++++++++++++++++++++++++++++
 spec/unit/type/file/mtime.rb  |   44 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 125 insertions(+), 0 deletions(-)
 create mode 100644 lib/puppet/type/file/ctime.rb
 create mode 100644 lib/puppet/type/file/mtime.rb
 create mode 100644 spec/unit/type/file/ctime.rb
 create mode 100644 spec/unit/type/file/mtime.rb

diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb
index 6523c99..eee948c 100644
--- a/lib/puppet/type/file.rb
+++ b/lib/puppet/type/file.rb
@@ -797,3 +797,5 @@ require 'puppet/type/file/group'
 require 'puppet/type/file/mode'
 require 'puppet/type/file/type'
 require 'puppet/type/file/selcontext'  # SELinux file context
+require 'puppet/type/file/ctime'
+require 'puppet/type/file/mtime'
diff --git a/lib/puppet/type/file/ctime.rb b/lib/puppet/type/file/ctime.rb
new file mode 100644
index 0000000..33ea734
--- /dev/null
+++ b/lib/puppet/type/file/ctime.rb
@@ -0,0 +1,18 @@
+module Puppet
+  Puppet::Type.type(:file).newproperty(:ctime) do
+    desc "A read-only state to check the file ctime."
+
+    def retrieve
+      current_value = :absent
+      if stat = @resource.stat(false)
+        current_value = stat.ctime
+      end
+      current_value
+    end
+
+    def sync
+      raise Puppet::Error, ":ctime is read-only"
+    end
+  end
+end
+
diff --git a/lib/puppet/type/file/mtime.rb b/lib/puppet/type/file/mtime.rb
new file mode 100644
index 0000000..0f03bf0
--- /dev/null
+++ b/lib/puppet/type/file/mtime.rb
@@ -0,0 +1,17 @@
+module Puppet
+  Puppet::Type.type(:file).newproperty(:mtime) do
+    desc "A read-only state to check the file mtime."
+
+    def retrieve
+      current_value = :absent
+      if stat = @resource.stat(false)
+        current_value = stat.mtime
+      end
+      current_value
+    end
+
+    def sync
+      raise Puppet::Error, ":mtime is read-only"
+    end
+  end
+end
diff --git a/spec/unit/type/file/ctime.rb b/spec/unit/type/file/ctime.rb
new file mode 100644
index 0000000..2c50e35
--- /dev/null
+++ b/spec/unit/type/file/ctime.rb
@@ -0,0 +1,44 @@
+#!/usr/bin/env ruby
+
+Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? 
require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
+
+source = Puppet::Type.type(:file).attrclass(:source)
+describe Puppet::Type.type(:file).attrclass(:source) do
+  require 'puppet_spec/files'
+  include PuppetSpec::Files
+
+  before do
+    @filename = tmpfile('ctime')
+    @resource = Puppet::Type.type(:file).new({:name => @filename})
+  end
+
+  it "should be able to audit the file's ctime" do
+    File.open(@filename, "w"){ }
+
+    @resource[:audit] = [:ctime]
+
+    # this .to_resource audit behavior is magical :-(
+    @resource.to_resource[:ctime].should == File.stat(@filename).ctime
+  end
+
+  it "should return absent if auditing an absent file" do
+    @resource[:audit] = [:ctime]
+
+    @resource.to_resource[:ctime].should == :absent
+  end
+
+  it "should prevent the user from trying to set the ctime" do
+    File.open(@filename, "w"){ }
+    @resource[:ctime] = Time.now
+
+    catalog = Puppet::Resource::Catalog.new()
+    catalog.add_resource(@resource)
+    Puppet::Util::Storage.stubs(:load)
+    Puppet::Util::Storage.stubs(:store)
+
+    transaction = catalog.apply
+    transaction.events.first.status.should == 'failure'
+    transaction.events.first.message.should =~ /ctime is read-only/
+  end
+
+end
diff --git a/spec/unit/type/file/mtime.rb b/spec/unit/type/file/mtime.rb
new file mode 100644
index 0000000..b709a7f
--- /dev/null
+++ b/spec/unit/type/file/mtime.rb
@@ -0,0 +1,44 @@
+#!/usr/bin/env ruby
+
+Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? 
require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
+
+source = Puppet::Type.type(:file).attrclass(:source)
+describe Puppet::Type.type(:file).attrclass(:source) do
+  require 'puppet_spec/files'
+  include PuppetSpec::Files
+
+  before do
+    @filename = tmpfile('mtime')
+    @resource = Puppet::Type.type(:file).new({:name => @filename})
+  end
+
+  it "should be able to audit the file's mtime" do
+    File.open(@filename, "w"){ }
+
+    @resource[:audit] = [:mtime]
+
+    # this .to_resource audit behavior is magical :-(
+    @resource.to_resource[:mtime].should == File.stat(@filename).mtime
+  end
+
+  it "should return absent if auditing an absent file" do
+    @resource[:audit] = [:mtime]
+
+    @resource.to_resource[:mtime].should == :absent
+  end
+
+  it "should prevent the user from trying to set the mtime" do
+    File.open(@filename, "w"){ }
+    @resource[:mtime] = Time.now
+
+    catalog = Puppet::Resource::Catalog.new()
+    catalog.add_resource(@resource)
+    Puppet::Util::Storage.stubs(:load)
+    Puppet::Util::Storage.stubs(:store)
+
+    transaction = catalog.apply
+    transaction.events.first.status.should == 'failure'
+    transaction.events.first.message.should =~ /mtime is read-only/
+  end
+
+end
-- 
1.7.0.4

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to