Permalink
Browse files

Improvements to option parsing:

- new GLI based skewer script
- new Command object to call from former
- generated rdoc
  • Loading branch information...
1 parent e92c3e5 commit 81e4b2f18e896040181f267e230990d0fde25761 @simpsonjulian simpsonjulian committed May 14, 2012
Showing with 289 additions and 4 deletions.
  1. +138 −0 bin/new_skewer
  2. +4 −4 lib/aws/node.rb
  3. +13 −0 lib/skewer/command.rb
  4. +20 −0 lib/skewer/command/update.rb
  5. +68 −0 skewer.rdoc
  6. +29 −0 spec/skewer/command/update_command_spec.rb
  7. +17 −0 spec/skewer/command_spec.rb
View
@@ -0,0 +1,138 @@
+#!/usr/bin/env ruby
+# 1.9 adds realpath to resolve symlinks; 1.8 doesn't
+# have this method, so we add it so we get resolved symlinks
+# and compatibility
+unless File.respond_to? :realpath
+ class File #:nodoc:
+ def self.realpath path
+ return realpath(File.readlink(path)) if symlink?(path)
+ path
+ end
+ end
+end
+$: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
+require 'rubygems'
+require 'gli'
+require 'skewer/version'
+
+include GLI
+
+program_desc 'Runs Puppet on cloud machines, with no PuppetMaster'
+
+version Skewer::VERSION
+
+desc 'Location of your Puppet Codebase'
+switch [:pc,:puppetcode]
+default_value '../infrastructure'
+
+desc 'Hook script to invoke, after the Puppet run success'
+switch [:hk,:hook]
+
+desc 'Cucumber features directory to invoke, after the Puppet run success'
+switch [:features]
+
+desc 'do a dry run first'
+default_value false
+arg_name 'noop'
+flag [:n,:noop]
+
+desc 'mock every fog call'
+default_value false
+arg_name 'fog mock'
+flag [:m,:mock]
+
+desc 'Update the puppet code on a machine that you have already provisioned'
+command :update do |c|
+ c.desc 'Host to update'
+ c.flag [:ho, :host]
+
+ c.desc 'User to run the update as'
+ c.flag [:u,:user]
+
+ c.desc 'Puppet role class to call on the remote machine'
+ c.flag [:r, :role]
+
+ c.action do |global_options,options,args|
+ require 'skewer/command/update'
+ puts options.inspect
+ puts global_options.inspect
+ Skewer::Command::Update.new(global_options, options).execute
+ end
+end
+
+desc 'Instantiate a cloud node, and run Puppet on it'
+command :provision do |c|
+
+
+ c.desc 'Kind of cloud: ec2 or rackspace'
+ c.default_value 'ec2'
+ c.arg_name 'cloud'
+ c.flag [:c,:cloud]
+
+ c.desc 'Retain the cloud instance, for posterity'
+ c.default_value false
+ c.arg_name 'keep'
+ c.flag :keep
+
+ c.desc 'Cloud service image identifier'
+ #c.arg_name 'image'
+ c.switch [:i, :image]
+
+ c.desc 'Cloud region to work in'
+ c.default_value 'us-east-1'
+ c.arg_name 'region'
+ c.flag [:region]
+
+ c.desc 'Security Group to use'
+ c.default_value 'default'
+ c.arg_name 'group'
+ c.flag :group
+
+ c.desc 'Kind of machine to use'
+ c.default_value 'm1.large'
+ c.arg_name 'flavour'
+ c.flag :flavor
+
+ c.desc 'Puppet role class to call on the remote machine'
+ c.switch [:r, :role]
+
+ c.desc 'SSH key to connect with (probably registered with your cloud provider'
+ c.switch [:k, :key]
+
+ c.action do |global_options,options,args|
+ end
+end
+
+desc 'deletes the given host from the provided cloud provider'
+arg_name 'Node hostname or id'
+command :delete do |c|
+ c.desc 'Cloud region to work in'
+ c.default_value 'us-east-1'
+ c.arg_name 'region'
+ c.flag [:region]
+ c.action do |global_options,options,args|
+ end
+end
+
+pre do |global,command,options,args|
+ # Pre logic here
+ # Return true to proceed; false to abort and not call the
+ # chosen command
+ # Use skips_pre before a command to skip this block
+ # on that command only
+ true
+end
+
+post do |global,command,options,args|
+ # Post logic here
+ # Use skips_post before a command to skip this
+ # block on that command only
+end
+
+on_error do |exception|
+ # Error logic here
+ # return false to skip default error handling
+ true
+end
+
+exit GLI.run(ARGV)
View
@@ -13,10 +13,10 @@ def initialize(aws_id, group_names, options = {})
else
@service = self.class.find_service(options)
node_options = {
- :image_id => aws_id,
- :flavor_id => SkewerConfig.get('flavor_id'),
- :username => SkewerConfig.get('aws_username'),
- :groups => group_names
+ :image_id => aws_id,
+ :flavor_id => SkewerConfig.get('flavor_id'),
+ :username => SkewerConfig.get('aws_username'),
+ :groups => group_names
}
if options[:key_name]
View
@@ -0,0 +1,13 @@
+module Skewer
+ class SkewerCommand
+ require 'config'
+ attr_reader :config
+
+ def initialize(global, local)
+ #puts Command.inspect
+ @config = SkewerConfig.instance
+ @config.slurp_options(global )
+ @config.slurp_options(local )
+ end
+ end
+end
@@ -0,0 +1,20 @@
+require 'skewer/command'
+module Skewer
+ module Command
+ class Update < Skewer::SkewerCommand
+ def initialize(global_options, options)
+
+ raise "Sorry, I need a user, role and host for this command" unless options[:user] && options[:role] && options[:host]
+ #raise "Sorry, that's a bad value of 'mock" unless [true, false].include?(global_options[:mock])
+
+
+
+ end
+
+ def execute
+
+ end
+
+ end
+ end
+end
View
@@ -0,0 +1,68 @@
+= <tt>skewer</tt>
+
+Runs Puppet on cloud machines, with no PuppetMaster
+
+ skewer [global options] command_name [command-specific options] [--] arguments...
+
+* Use the command +help+ to get a summary of commands
+* Use the command <tt>help command_name</tt> to get a help for +command_name+
+* Use <tt>--</tt> to stop command line argument processing; useful if your arguments have dashes in them
+
+== Global Options
+These options are available for any command and are specified before the name of the command
+
+[<tt>--features</tt>] Cucumber features directory to invoke, after the Puppet run success
+[<tt>--help</tt>] Show this message
+[<tt>--hk, --hook</tt>] Hook script to invoke, after the Puppet run success
+[<tt>-m, --mock=fog mock</tt>] mock every fog call
+[<tt>-n, --noop=noop</tt>] do a dry run first
+[<tt>--pc, --puppetcode</tt>] Location of your Puppet Codebase
+== Commands
+[<tt>delete</tt>] deletes the given host from the provided cloud provider
+[<tt>help</tt>] Shows list of commands or help for one command
+[<tt>provision</tt>] Instantiate a cloud node, and run Puppet on it
+[<tt>update</tt>] Update the puppet code on a machine that you have already provisioned
+
+=== <tt>delete Node hostname or id</tt>
+
+deletes the given host from the provided cloud provider
+
+==== Options
+These options are specified *after* the command.
+
+[<tt>--region=region</tt>] Cloud region to work in <i>( default: <tt>us-east-1</tt>)</i>
+=== <tt>help [command]</tt>
+
+Shows list of commands or help for one command
+
+Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function
+
+==== Options
+These options are specified *after* the command.
+
+[<tt>-c, --completion</tt>] List all commands one line at a time, for use with shell completion ([command] argument is partial command to match)
+=== <tt>provision </tt>
+
+Instantiate a cloud node, and run Puppet on it
+
+==== Options
+These options are specified *after* the command.
+
+[<tt>-c, --cloud=cloud</tt>] Kind of cloud: ec2 or rackspace <i>( default: <tt>ec2</tt>)</i>
+[<tt>--flavor=flavour</tt>] Kind of machine to use <i>( default: <tt>m1.large</tt>)</i>
+[<tt>--group=group</tt>] Security Group to use <i>( default: <tt>default</tt>)</i>
+[<tt>-i, --image</tt>] Cloud service image identifier
+[<tt>-k, --key</tt>] SSH key to connect with (probably registered with your cloud provider
+[<tt>--keep=keep</tt>] Retain the cloud instance, for posterity
+[<tt>-r, --role</tt>] Puppet role class to call on the remote machine
+[<tt>--region=region</tt>] Cloud region to work in <i>( default: <tt>us-east-1</tt>)</i>
+=== <tt>update </tt>
+
+Update the puppet code on a machine that you have already provisioned
+
+==== Options
+These options are specified *after* the command.
+
+[<tt>--host</tt>] Host to update
+[<tt>-r, --role</tt>] Puppet role class to call on the remote machine
+[<tt>-u, --user</tt>] User to run the update as
@@ -0,0 +1,29 @@
+require "rspec"
+require 'skewer/command/update'
+
+describe "Update" do
+
+ it "should blow up if it doesn't have options'" do
+ lambda {
+ Skewer::Command::Update.new({}, {})
+ }.should raise_error RuntimeError
+ end
+
+ it "should blow up with a duff noop" do
+ pending('later')
+ end
+
+ it "should blow up with a duff mock" do
+ pending('later')
+ end
+
+ it "should inherit lots of good stuff" do
+ Skewer::Command::Update.new({}, {:role => ' ', :user => ' ', :host => ' '}).class.superclass.should == Skewer::SkewerCommand
+ end
+
+ it "should delegate to something that is going to do the work" do
+ pending('later')
+ end
+
+
+end
@@ -0,0 +1,17 @@
+require "rspec"
+require 'skewer/command'
+require 'config'
+
+describe "Commands" do
+
+ it "should know about config" do
+
+ Skewer::SkewerCommand.new({},{}).config.class.should == Skewer::SkewerConfig
+ end
+
+ it "should slurp all the options" do
+ skewer_command = Skewer::SkewerCommand.new({:foo => 'bar'}, {:baz => 'goo'})
+ skewer_command.config.get(:foo).should == 'bar'
+ skewer_command.config.get(:baz).should == 'goo'
+ end
+end

0 comments on commit 81e4b2f

Please sign in to comment.