invoking knife in a ruby class

a 夏天 提交于 2019-12-09 07:01:56

问题


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?


回答1:


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.




回答2:


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).




回答3:


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



回答4:


Knife does parsing itself.

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


来源:https://stackoverflow.com/questions/16826003/invoking-knife-in-a-ruby-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!