[chef] Re: Re: Re: Re: Knife bash completion - improved


Chronological Thread 
  • From: Avishai Ish-Shalom < >
  • To:
  • Subject: [chef] Re: Re: Re: Re: Knife bash completion - improved
  • Date: Thu, 20 Jan 2011 18:10:41 +0200
  • Organization: FewBytes Technologies

Great to hear you got it working on OSX.

You may be interested to know that I too am working with several chef servers. The problem is that bash_completion can not take into account the knife -c switch because it appears late on the command line. There are several work-arounds for this, the easiest would be

knife () {

    /absolute/path/to/knife $@ -c $CHEF_HOME/.chef/knife.rb

}

then set CHEF_HOME to a different directory when working with the other server. If, like me, you are constantly switching between chef servers it's convenient to set multiple knife functions, e.g.: server1_knife. This is what I do and it did require modifications to the script - revised version attached.

The revised version should work for regular knife as well, and feature data bag completion for bags and items.

Regards,
Avishai

On 01/20/2011 05:46 PM, Jacobo García wrote:
" type="cite">Hello,

Thanks for your script, it's great, specially for beginers on the chef CLI.

I tried your script in OS X too and the problems are related to differences between GNU sed and BSD sed. I just quick fixed them installing gsed with macports and changing sed references to gsed.

Also it's possible to have a knife config file per chef repository instead of ~/.chef/knife.rb. This way you can work over several chef servers. I am not sure how to fix that in the script but probably there's some clues on knife code. I found the script crashing here too.

Greetings.

Jacobo García López de Araujo
blog: http://robotplaysguitar.com
http://workingwithrails.com/person/13395-jacobo-garc-a



On Thu, Jan 20, 2011 at 3:40 PM, Avishai Ish-Shalom < "> > wrote:
Well, my wife has a mac. I'll try to arm wrestle her for some quality
time with it later today.

Regards,
Avishai


On 01/20/2011 04:36 PM, Jacob Vanderdray wrote:
>       This sounded helpful enough that I gave it a shot.  I'm using a Mac, so I ran into a few issues.  Unfortunately I still don't have it working past the first knife parameter (i.e. if I type "knife cook" and hit <tab> I end up with "knife cookbook", but when I type "knife cookbook upl" and hit tab I get an error.  I'm going to give up for now, but if you're interested here's what I had to do (This is mostly from memory so YMMV):
>
> Use Macports to install bash-completion:
>  sudo port install bash-completion
>
> Update ~/.bash_profile with:
>
> # MacPorts Bash shell command completion
> if [ -f /opt/local/etc/bash_completion ]; then
>    . /opt/local/etc/bash_completion
> fi
>
> The version of sed used in this script uses "-r" to get extended regular expressions, but for the version of sed on my Mac I had to change that to "-E".  If someone works out the rest, I'd be interested.
>
> Thanks,
> Jake.
>
> On Jan 20, 2011, at 4:06 AM, Avishai Ish-Shalom wrote:
>
>> OK. Now it works fast, used cache files for command completions and
>> while i was at it i added roles and nodes completion.
>>
>> Cache files reside in $CHEF_HOME/.completion_cache and you have to
>> create this directory if you want cached completion.
>>
>>
>> And yes, now it will read chef repository locations from either
>> CHEF_REPOS or $CHEF_HOME/knife.rb
>>
>>
>> enjoy.
>>
>> Avishai
>>
>> <knife.txt>

# vim: ft=sh:ts=4:sw=4:autoindent:
# Author: Avishai Ish-Shalom 
< >

# first argument set the command level
_get_knife_completions() {
        n=$1
        shift
        # first argument is knife, so shift it
        #[ "$1" == "knife" ] && shift
        local opts
        opts="$($@ --help | grep -E '^knife' | cut -f$n -d" " | grep -v 
'(options)')"
        _upvar opts "$opts"
}

_flatten_knife_command() {
    echo ${words[*]} |sed -r -e "s/\ *${words[$cword]}\$//" -e 's/\W/_/g'
}
# Check cache file for category ( passed as $1 ) and run command if cache is 
empty
# Designed to be used with _get_knife_completions() and use the opts 
variables for options
_completion_cache() {
    local CACHE_DIR=${CHEF_HOME:-"$HOME/.chef"}/.completion_cache
    local flag COMMAND
    local OPTIND=1
    while getopts "c" flag "$@"; do
        case $flag in
        c)
            COMMAND=yes
            ;;
        *)
            ;;
        esac
    done
    shift $(( $OPTIND - 1 ))

    local CACHE_FILE="$CACHE_DIR/$1"
    shift
    if [ ! -f "$CACHE_FILE" ]; then
                if [[ "$COMMAND" == "yes" ]]; then
                        opts=$( eval $@ )
                else
                        $@
                fi
                [ -d "$CACHE_DIR" ] && echo $opts >"$CACHE_FILE"
    else
        opts=$(cat "$CACHE_FILE")
    fi
    _upvar opts "$opts"
}

_knife() {
        local opts cur prev cword words flattened_knife_command
        opts="bootstrap client configure cookbook data ec2 exec index node 
rackspace recipe role search slicehost ssh status terremark windows"
        _get_comp_words_by_ref cur prev cword words
    flattened_knife_command=$(_flatten_knife_command)
        COMPREPLY=()
        case $flattened_knife_command in
        *knife_cookbook_upload)
        local chef_repos
                if [[ -z $CHEF_REPOS ]]; then
            chef_repos=( $(sed -rn '/cookbook_path/ {s/.*\[(.*)\]/\1/g; 
s/[,'\'']//g; p}' ${CHEF_HOME:-"$HOME/.chef"}/knife.rb) )
        else
            chef_repos=( 

 )
        fi
        if [[ -n "$chef_repos" ]]; then
            opts=$( ls -1p 

 | sort -u | sed -n 's/\/$//p' )
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        fi
                ;;
    *knife_data)
        opts="bag"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
    *knife_node_show|*knife_node_edit|*knife_node_delete)
        _completion_cache -c knife_nodes "${words[0]} node list|sed -r -e 
's/[\"\ ,]//g' -e '/[^\.a-z0-9\-]+/d'"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
    *knife_role_edit|*knife_role_show|*knife_role_delete)
        _completion_cache -c knife_roles "${words[0]} role list|sed -r -e 
's/[\"\ ,]//g' -e '/[^\.a-z0-9\-]+/d'"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
    *knife_data_bag_delete|*knife_data_bag_show|*knife_data_bag_edit)
        _completion_cache -c knife_data_bags "${words[0]} data bag list|sed 
-r -e 's/[\"\ ,]//g' -e '/[^\.a-z0-9\-]+/d'"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
        
*knife_data_bag_delete_*|*knife_data_bag_show_*|*knife_data_bag_edit_*)
        _completion_cache -c knife_data_bag_$prev "${words[0]} data bag show 
$prev 2>/dev/null|sed -r -e 's/[\"\ ,]//g' -e '/^[^a-zA-Z0-9_.-].*/d'"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
    *knife_client_list|*knife_client_show|*knife_client_edit)
        _completion_cache -c knife_clients "${words[0]} client list|sed -r -e 
's/[\"\ ,]//g' -e '/[^\.a-z0-9\-]+/d'"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
        *)
                case $cword in
                1)
                        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
                        return 0
                        ;;
                *)
            _completion_cache $flattened_knife_command  
_get_knife_completions $(( $cword + 1 )) ${words[*]}
                        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
                        return 0
                        ;;
                esac
                ;;
        esac
        [[ 

 -ge 1 ]] && return 0
}
complete -F _knife knife



Archive powered by MHonArc 2.6.16.

§