#!/usr/bin/env ruby # # = Synopsis # # A stand-alone Puppet filebucket client. # # = Usage # # filebucket [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] # [-l|--local] [-r|--remote] # [-s|--server ] [-b|--bucket ] ... # # = Description # # This is a stand-alone filebucket client for sending files to a local # or central filebucket. # # = Usage # # This client can operate in three modes, with only one mode per call: # # backup:: # Send one or more files to the specified file bucket. Each sent file # is printed with its resulting md5 sum. # # get:: # Return the text associated with an md5 sum. The text is printed to # stdout, and only one file can be retrieved at a time. # # restore:: # Given a file path and an md5 sum, store the content associated with the # sum into the specified file path. You can specify an entirely new path # to this argument; you are not restricted to restoring the content to its # original location. # # Note that +filebucket+ defaults to using a network-based filebucket available on # the server named +puppet+. To use this, you'll have to be running as a user # with valid Puppet certificates. Alternatively, you can use your local file bucket # by specifying +--local+. # # = Example # # $ filebucket backup /etc/passwd # /etc/passwd: 429b225650b912a2ee067b0a4cf1e949 # $ filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 # $ # # = Options # # Note that any configuration parameter that's valid in the configuration file # is also a valid long argument. For example, 'ssldir' is a valid configuration # parameter, so you can specify '--ssldir ' as an argument. # # See the configuration file documentation at # http://reductivelabs.com/projects/puppet/reference/configref.html for # the full list of acceptable parameters. A commented list of all # configuration options can also be generated by running puppet with # '--genconfig'. # # debug:: # Enable full debugging. # # help:: # Print this help message # # local:: # Use the local filebucket. This will use the default configuration # information. # # remote:: # Use a remote filebucket. This will use the default configuration # information. # # server:: # The server to send the file to, instead of locally. # # verbose:: # Print extra information. # # version:: # Print version information. # # = Example # # filebucket -b /tmp/filebucket /my/file # # = Author # # Luke Kanies # # = Copyright # # Copyright (c) 2005 Reductive Labs, LLC # Licensed under the GNU Public License require 'puppet' require 'puppet/network/client' require 'getoptlong' options = [ [ "--bucket", "-b", GetoptLong::REQUIRED_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--local", "-l", GetoptLong::NO_ARGUMENT ], [ "--remote", "-r", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "--version", "-V", GetoptLong::NO_ARGUMENT ] ] # Add all of the config parameters as valid options. Puppet.settings.addargs(options) result = GetoptLong.new(*options) options = {} begin result.each { |opt,arg| case opt when "--version" puts "%s" % Puppet.version exit when "--help" if Puppet.features.usage? RDoc::usage && exit else puts "No help available unless you have RDoc::usage installed" exit end when "--bucket" options[:bucket] = arg when "--verbose" options[:verbose] = true when "--debug" options[:debug] = true when "--local" options[:local] = true when "--remote" options[:remote] = true else Puppet.settings.handlearg(opt, arg) end } rescue GetoptLong::InvalidOption => detail $stderr.puts "Try '#{$0} --help'" exit(1) end Puppet::Log.newdestination(:console) client = nil server = nil Puppet.settraps if options[:debug] Puppet::Log.level = :debug elsif options[:verbose] Puppet::Log.level = :info end # Now parse the config Puppet.parse_config if Puppet.settings.print_configs? exit(Puppet.settings.print_configs ? 0 : 1) end begin if options[:local] or options[:bucket] path = options[:bucket] || Puppet[:bucketdir] client = Puppet::Network::Client.dipper.new(:Path => path) else require 'puppet/network/handler' client = Puppet::Network::Client.dipper.new(:Server => Puppet[:server]) end rescue => detail $stderr.puts detail if Puppet[:trace] puts detail.backtrace end exit(1) end mode = ARGV.shift case mode when "get": md5 = ARGV.shift out = client.getfile(md5) print out when "backup": ARGV.each do |file| unless FileTest.exists?(file) $stderr.puts "%s: no such file" % file next end unless FileTest.readable?(file) $stderr.puts "%s: cannot read file" % file next end md5 = client.backup(file) puts "%s: %s" % [file, md5] end when "restore": file = ARGV.shift md5 = ARGV.shift client.restore(file, md5) else raise "Invalid mode %s" % mode end