diff --git a/lib/puppet/application/filebucket.rb b/lib/puppet/application/filebucket.rb index 6d59ae40b..f78e9370a 100644 --- a/lib/puppet/application/filebucket.rb +++ b/lib/puppet/application/filebucket.rb @@ -1,189 +1,191 @@ require 'puppet/application' class Puppet::Application::Filebucket < Puppet::Application should_not_parse_config option("--bucket BUCKET","-b") option("--debug","-d") option("--local","-l") option("--remote","-r") option("--verbose","-v") attr :args def help <<-HELP puppet-filebucket(8) -- Store and retrieve files in a filebucket ======== SYNOPSIS -------- A stand-alone Puppet filebucket client. USAGE ----- puppet filebucket [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] [-l|--local] [-r|--remote] [-s|--server ] [-b|--bucket ] ... Puppet filebucket 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. DESCRIPTION ----------- This is a stand-alone filebucket client for sending files to a local or central filebucket. 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'. 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://docs.puppetlabs.com/references/stable/configuration.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 ------- $ puppet filebucket backup /etc/passwd /etc/passwd: 429b225650b912a2ee067b0a4cf1e949 $ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 AUTHOR ------ Luke Kanies COPYRIGHT --------- Copyright (c) 2011 Puppet Labs, LLC Licensed under the Apache 2.0 License HELP end def run_command @args = command_line.args command = args.shift return send(command) if %w{get backup restore}.include? command help end def get md5 = args.shift out = @client.getfile(md5) print out end def backup + raise "You must specify a file to back up" unless args.length > 0 + args.each do |file| unless FileTest.exists?(file) $stderr.puts "#{file}: no such file" next end unless FileTest.readable?(file) $stderr.puts "#{file}: cannot read file" next end md5 = @client.backup(file) puts "#{file}: #{md5}" end end def restore file = args.shift md5 = args.shift @client.restore(file, md5) end def setup Puppet::Log.newdestination(:console) @client = nil @server = nil Signal.trap(:INT) do $stderr.puts "Cancelling" exit(1) end if options[:debug] Puppet::Log.level = :debug elsif options[:verbose] Puppet::Log.level = :info end # Now parse the config Puppet.parse_config exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs? require 'puppet/file_bucket/dipper' begin if options[:local] or options[:bucket] path = options[:bucket] || Puppet[:bucketdir] @client = Puppet::FileBucket::Dipper.new(:Path => path) else @client = Puppet::FileBucket::Dipper.new(:Server => Puppet[:server]) end rescue => detail $stderr.puts detail puts detail.backtrace if Puppet[:trace] exit(1) end end end diff --git a/spec/unit/application/filebucket_spec.rb b/spec/unit/application/filebucket_spec.rb index ee30e7d12..372a08095 100755 --- a/spec/unit/application/filebucket_spec.rb +++ b/spec/unit/application/filebucket_spec.rb @@ -1,213 +1,218 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/application/filebucket' require 'puppet/file_bucket/dipper' describe Puppet::Application::Filebucket do before :each do @filebucket = Puppet::Application[:filebucket] end it "should ask Puppet::Application to not parse Puppet configuration file" do @filebucket.should_parse_config?.should be_false end it "should declare a get command" do @filebucket.should respond_to(:get) end it "should declare a backup command" do @filebucket.should respond_to(:backup) end it "should declare a restore command" do @filebucket.should respond_to(:restore) end [:bucket, :debug, :local, :remote, :verbose].each do |option| it "should declare handle_#{option} method" do @filebucket.should respond_to("handle_#{option}".to_sym) end it "should store argument value when calling handle_#{option}" do @filebucket.options.expects(:[]=).with("#{option}".to_sym, 'arg') @filebucket.send("handle_#{option}".to_sym, 'arg') end end describe "during setup" do before :each do Puppet::Log.stubs(:newdestination) Puppet.stubs(:settraps) Puppet.stubs(:parse_config) Puppet::FileBucket::Dipper.stubs(:new) @filebucket.options.stubs(:[]).with(any_parameters) end it "should set console as the log destination" do Puppet::Log.expects(:newdestination).with(:console) @filebucket.setup end it "should trap INT" do Signal.expects(:trap).with(:INT) @filebucket.setup end it "should set log level to debug if --debug was passed" do @filebucket.options.stubs(:[]).with(:debug).returns(true) @filebucket.setup Puppet::Log.level.should == :debug end it "should set log level to info if --verbose was passed" do @filebucket.options.stubs(:[]).with(:verbose).returns(true) @filebucket.setup Puppet::Log.level.should == :info end it "should Parse puppet config" do Puppet.expects(:parse_config) @filebucket.setup end it "should print puppet config if asked to in Puppet config" do Puppet.settings.stubs(:print_configs?).returns(true) Puppet.settings.expects(:print_configs).returns(true) expect { @filebucket.setup }.to exit_with 0 end it "should exit after printing puppet config if asked to in Puppet config" do Puppet.settings.stubs(:print_configs?).returns(true) expect { @filebucket.setup }.to exit_with 1 end describe "with local bucket" do before :each do @filebucket.options.stubs(:[]).with(:local).returns(true) end it "should create a client with the default bucket if none passed" do Puppet.stubs(:[]).with(:bucketdir).returns("path") Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Path] == "path" } @filebucket.setup end it "should create a local Dipper with the given bucket" do @filebucket.options.stubs(:[]).with(:bucket).returns("path") Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Path] == "path" } @filebucket.setup end end describe "with remote bucket" do it "should create a remote Client to the configured server" do Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com") Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Server] == "puppet.reductivelabs.com" } @filebucket.setup end end end describe "when running" do before :each do Puppet::Log.stubs(:newdestination) Puppet.stubs(:settraps) Puppet.stubs(:parse_config) Puppet::FileBucket::Dipper.stubs(:new) @filebucket.options.stubs(:[]).with(any_parameters) @client = stub 'client' Puppet::FileBucket::Dipper.stubs(:new).returns(@client) @filebucket.setup end it "should use the first non-option parameter as the dispatch" do @filebucket.command_line.stubs(:args).returns(['get']) @filebucket.expects(:get) @filebucket.run_command end describe "the command get" do before :each do @filebucket.stubs(:print) @filebucket.stubs(:args).returns([]) end it "should call the client getfile method" do @client.expects(:getfile) @filebucket.get end it "should call the client getfile method with the given md5" do md5="DEADBEEF" @filebucket.stubs(:args).returns([md5]) @client.expects(:getfile).with(md5) @filebucket.get end it "should print the file content" do @client.stubs(:getfile).returns("content") @filebucket.expects(:print).returns("content") @filebucket.get end end describe "the command backup" do + it "should fail if no arguments are specified" do + @filebucket.stubs(:args).returns([]) + lambda { @filebucket.backup }.should raise_error + end + it "should call the client backup method for each given parameter" do @filebucket.stubs(:puts) FileTest.stubs(:exists?).returns(true) FileTest.stubs(:readable?).returns(true) @filebucket.stubs(:args).returns(["file1", "file2"]) @client.expects(:backup).with("file1") @client.expects(:backup).with("file2") @filebucket.backup end end describe "the command restore" do it "should call the client getfile method with the given md5" do md5="DEADBEEF" file="testfile" @filebucket.stubs(:args).returns([file, md5]) @client.expects(:restore).with(file,md5) @filebucket.restore end end end end