Please review pull request #779: Add Two option for filebucket: list and diff opened by (emilemorel)

Description:

List: List all files in the current filebucket.
diff: Print a diff between two md5 in the filebucket or between a md5sum and its matching file.

  • Opened: Tue May 15 07:50:02 UTC 2012
  • Based on: puppetlabs:master (a98969c1374b80408bce308dc7154e17a723df6c)
  • Requested merge: emilemorel:improv_filebucket (6d8501e40c1de9d9b29d08e06e06733917149ff6)

Diff follows:

diff --git a/lib/puppet/application/filebucket.rb b/lib/puppet/application/filebucket.rb
index 174f3d1..68e6645 100644
--- a/lib/puppet/application/filebucket.rb
+++ b/lib/puppet/application/filebucket.rb
@@ -3,6 +3,8 @@
 class Puppet::Application::Filebucket < Puppet::Application
 
   option("--bucket BUCKET","-b")
+  option("--fromdate FROMDATE", "-f")
+  option("--todate TODATE", "-t")
   option("--debug","-d")
   option("--local","-l")
   option("--remote","-r")
@@ -25,7 +27,7 @@ def help
 -----
 puppet filebucket <mode> [-h|--help] [-V|--version] [-d|--debug]
   [-v|--verbose] [-l|--local] [-r|--remote] [-s|--server <server>]
-  [-b|--bucket <directory>] <file> <file> ...
+  [-b|--bucket <directory>] [list] [diff] <file> <file> ...
 
 Puppet filebucket can operate in three modes, with only one mode per call:
 
@@ -43,6 +45,12 @@ def help
   path to this argument; you are not restricted to restoring the content
   to its original location.
 
+list:
+  List all files in the current filebucket.
+
+diff:
+  Print a diff between two md5 in the filebucket or between a md5sum and its
+  matching file.
 
 DESCRIPTION
 -----------
@@ -91,6 +99,11 @@ def help
 * --version:
   Print version information.
 
+* --fromdate:
+  Select bucket files from 'fromdate' (list only)
+
+* --todate:
+   Select bucket files until 'todate' (list only)
 
 EXAMPLE
 -------
@@ -98,6 +111,22 @@ def help
     /etc/passwd: 429b225650b912a2ee067b0a4cf1e949
     $ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949
 
+    $ filebucket -l list --fromdate "2010-09-14 12:04:44"
+    8486f097057436a7d675f68c327f625d 2010-09-14 12:04:48 /etc/fstab
+    0b42e60883a33034f1bec7dba55e5018 2010-10-05 13:29:56 /etc/gitconfig
+    9f537de00f864ce8e8b06293f2f6a4a8 2010-10-05 13:33:17 /etc/gitconfig
+    32556201d742291bb64fec741ad7b128 2010-10-05 17:27:27 /etc/gitconfig
+ 
+    $  filebucket -l diff c4cae6862561d1f605e8ba5acc7d07cd
+    --- /tmp/puppet-diffing-puppet.conf.21267.0     2010-10-11 13:42:22.000000000 +0200
+    +++ /etc/puppet/puppet.conf     2010-01-28 04:48:33.000000000 +0100
+    @@ -27,4 +27,4 @@
+      # extension indicating the cache format is added automatically.
+      # The default value is '$confdir/localconfig'.
+      localconfig = $vardir/localconfig
+    - environment = production
+    + environment = testing
+
 
 AUTHOR
 ------
@@ -115,7 +144,7 @@ def help
   def run_command
     @args = command_line.args
     command = args.shift
-    return send(command) if %w{get backup restore}.include? command
+    return send(command) if %w{get backup restore list diff}.include? command
     help
   end
 
@@ -148,6 +177,24 @@ def restore
     @client.restore(file, md5)
   end
 
+  def list
+    fromdate = options[:fromdate] || "0:0:0 1-1-1970"
+    todate = options[:todate] || Time.new.httpdate.to_s
+    out = @client.list(fromdate, todate)
+    print out
+  end
+
+  def diff
+    md5a = args.shift
+    md5b = args.shift || ''
+    if md5a
+      Puppet.info("Comparing #{md5a} #{md5b}")
+      print @client.diff(md5a, md5b)
+    else
+      $stderr.puts "Need at last one md5: filebucket diff #{ARGV} <md5a> <md5b>"
+    end
+  end
+
   def setup
     Puppet::Log.newdestination(:console)
 
diff --git a/lib/puppet/file_bucket/dipper.rb b/lib/puppet/file_bucket/dipper.rb
index a4cc9ed..d48ce35 100644
--- a/lib/puppet/file_bucket/dipper.rb
+++ b/lib/puppet/file_bucket/dipper.rb
@@ -52,6 +52,26 @@ def backup(file)
     end
   end
 
+  # List filebucket content.
+  def list(fromdate, todate)
+    source_path = "#{@rest_path}md5/"
+    fromdate ||= '1-1-1970'
+    todate ||= Time.now.httpdate.to_s
+    file_bucket_file = Puppet::FileBucket::File.indirection.find(source_path, :bucket_path => @local_path, :list_all => true, :fromdate => fromdate, :todate => todate)
+    raise Puppet::Error, "File not found" unless file_bucket_file
+    file_bucket_file.to_s
+  end
+
+  # Diff two filebucket files identified by their sum.
+  def diff(suma, sumb)
+    source_path = "#{@rest_path}md5/#{suma}"
+    file_bucket_file = Puppet::FileBucket::File.indirection.find(source_path, :bucket_path => @local_path, :diff_with => sumb)
+
+    raise Puppet::Error, "File not found" unless file_bucket_file
+    file_bucket_file.to_s
+  end
+
+
   # Retrieve a file by sum.
   def getfile(sum)
     source_path = "#{@rest_path}md5/#{sum}"
diff --git a/lib/puppet/indirector/file_bucket_file/file.rb b/lib/puppet/indirector/file_bucket_file/file.rb
index 231940d..14fbcb4 100644
--- a/lib/puppet/indirector/file_bucket_file/file.rb
+++ b/lib/puppet/indirector/file_bucket_file/file.rb
@@ -1,7 +1,10 @@
 require 'puppet/indirector/code'
 require 'puppet/file_bucket/file'
 require 'puppet/util/checksums'
+require 'puppet/util/diff'
 require 'fileutils'
+require 'pathname'
+require 'time'
 
 module Puppet::FileBucketFile
   class File < Puppet::Indirector::Code
@@ -14,6 +17,41 @@ def initialize
     end
 
     def find( request )
+      if not request.options[:bucket_path]
+       request.options[:bucket_path] = Puppet[:bucketdir]
+      end
+      if request.options[:list_all]
+        return '' unless ::File.exists?(request.options[:bucket_path])
+        fromdate = request.options[:fromdate] || "1-1-1970"
+        todate = request.options[:todate] || Time.now.httpdate.to_s
+        buck = {}
+        msg = ""
+        Pathname.new(request.options[:bucket_path]).find { |d|
+          if d.file?
+            if d.basename.to_s == "paths"
+              filename = d.read.strip
+              filestat = Time.parse(d.stat.mtime.to_s)
+              from = Time.parse(fromdate)
+              to = Time.parse(todate)
+              if Time.parse(fromdate) <= filestat and filestat <= Time.parse(todate.to_s)
+                if buck[filename]
+                  buck[filename] += [[ d.stat.mtime , d.parent.basename ]]
+                else
+                  buck[filename] = [[ d.stat.mtime , d.parent.basename ]]
+                end
+              end
+            end
+          end
+        }
+        buck.sort.each { |f, contents|
+          contents.sort.each { |d, chksum|
+            date = DateTime.parse(d.to_s).strftime("%F %T")
+            msg += "#{chksum} #{date} #{f}\n"
+          }
+        }
+        return model.new(msg)
+      end
+
       checksum, files_original_path = request_to_checksum_and_path( request )
       dir_path = path_for(request.options[:bucket_path], checksum)
       file_path = ::File.join(dir_path, 'contents')
@@ -23,9 +61,13 @@ def find( request )
 
       if request.options[:diff_with]
         hash_protocol = sumtype(checksum)
-        file2_path = path_for(request.options[:bucket_path], request.options[:diff_with], 'contents')
+        if request.options[:diff_with] != ''
+           file2_path = path_for(request.options[:bucket_path], request.options[:diff_with], 'contents')
+        else
+           file2_path = filename(request.options[:bucket_path],checksum)
+        end
         raise "could not find diff_with #{request.options[:diff_with]}" unless ::File.exists?(file2_path)
-        return `diff #{file_path.inspect} #{file2_path.inspect}`
+        return model.new(diff(file_path, file2_path))
       else
         contents = IO.binread(file_path)
         Puppet.info "FileBucket read #{checksum}"
@@ -103,12 +145,19 @@ def request_to_checksum_and_path( request )
       checksum_type, checksum, path = request.key.split(/\//, 3)
       if path == '' # Treat "md5/<checksum>/" like "md5/<checksum>"
         path = nil
+      else
+        path &&= "/#{path}" # Add '/' to the filepath: split removed it
       end
       raise "Unsupported checksum type #{checksum_type.inspect}" if checksum_type != 'md5'
       raise "Invalid checksum #{checksum.inspect}" if checksum !~ /^[0-9a-f]{32}$/
       [checksum, path]
     end
 
+    def filename(bucket_path, digest)
+      paths_path = path_for(bucket_path, digest, 'paths')
+      filepath = ::File.new(paths_path).read.strip
+    end
+
     def path_for(bucket_path, digest, subfile = nil)
       bucket_path ||= Puppet[:bucketdir]
 

    

--
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