jsookiki
jsookiki

Reputation: 542

invoking knife in a ruby class

I'd like to create a nice wrapper class around knife to allow a program to run knife commands in a readable manner. I'm currently trying to use the knife.rb file in the chef gem as a guide to some success. However, I'm having an issue turning off the editor. If I run the following code:

    require 'chef/knife'
    knife = Chef::Knife.new
    knife.run(['client', 'create', 'new-client'], '--disable-editing')

it results in the following error:

    NoMethodError: undefined method `merge!' for "--disable-editing":String

Anyone have any ideas on how to do this successfully? Is there a library by chance that already exists that does what I need?

Upvotes: 3

Views: 3623

Answers (4)

Daniil Iaitskov
Daniil Iaitskov

Reputation: 6079

Knife does parsing itself.

require 'chef/knife'
Chef::Knife.run(%w(bootstrap -N chef-n1 --sudo -x dan chef-n1.dan.lan))

Upvotes: 0

Bryan Huang
Bryan Huang

Reputation: 11

You could refer to following solution: http://lists.opscode.com/sympa/arc/chef/2011-08/msg00014.html

    require 'rubygems'
    require "chef"
    require "chef/knife/core/bootstrap_context"
    require 'chef/knife'
    require 'chef/knife/ssh'
    require 'net/ssh'
    require 'net/ssh/multi'
    require 'chef/knife/bootstrap'

    Chef::Config.from_file(File.expand_path('~/.chef/knife.rb'))
    kb = Chef::Knife::Bootstrap.new
    kb.name_args = "some.host"
    kb.config[:ssh_user] = "ubuntu"
    kb.config[:run_list] = "role[test]"
    kb.config[:use_sudo] = true
    kb.run

Upvotes: 1

jsookiki
jsookiki

Reputation: 542

So I was able to solve this problem. It does indeed want a hash, but it wants it to be a subset of the Mixlib::CLI class. So, this is the code needed to create a client via knife programmatically:

    class MyCLI
      include Mixlib::CLI
    end

    #Add the option for disable editing. If you look in knife help, it's --disable-editing
    MyCLI.option(:disable_editing, :long => "--disable-editing", :boolean => true)

    #instantiate knife object and add the disable-editing flag to it
    knife = Chef::Knife.new
    knife.options=MyCLI.options

    #set up client creation arguments and run
    args = ['client', 'create',  'new_client', '--disable-editing' ]  
    new_client = Chef::Knife.run(args, MyCLI.options)

It's not the most elegant solution, but it does use knife via the command line and saves someone from have to use a system call to use it.

Upvotes: 6

hmind
hmind

Reputation: 880

It looks like Knife is expecting a Hash where you have 'disable-editing'. Try this:

knife.run(['client', 'create', 'new-client'], {:"disable-editing" => true})

When something like this happens, try looking at the Array/Hash api docs to look for the method the error is spitting out. That will give you an idea of what should be going into that parameter (if you don't have documentation for the library and the source is hard to read).

Upvotes: 0

Related Questions