cuken 0.1.4 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. data/.relish +2 -0
  2. data/Gemfile +4 -4
  3. data/Gemfile.lock +17 -23
  4. data/VERSION +1 -1
  5. data/cuken.gems +108 -0
  6. data/cuken.gemspec +33 -10
  7. data/features/about.md +15 -2
  8. data/features/chef_examples/cookbooks_cookbook.feature +38 -3
  9. data/features/chef_examples/cookbooks_remote_repo.feature +10 -0
  10. data/features/chef_examples/cookbooks_repo.feature +5 -5
  11. data/features/{chef_steps → chef_examples}/knife_admin_client.feature +4 -4
  12. data/features/chef_examples/knife_client_create.feature +13 -0
  13. data/features/chef_steps/common_steps.feature +2 -2
  14. data/features/chef_steps/cookbook_steps.feature +12 -5
  15. data/features/chef_steps/node_steps.feature +1 -1
  16. data/features/file_steps/file_steps.feature +11 -11
  17. data/lib/cuken/all.rb +4 -0
  18. data/lib/cuken/api/chef/common.rb +46 -8
  19. data/lib/cuken/api/chef/knife.rb +107 -0
  20. data/lib/cuken/api/chef.rb +21 -13
  21. data/lib/cuken/api/common.rb +12 -0
  22. data/lib/cuken/api/rvm.rb +501 -0
  23. data/lib/cuken/api/ssh-forever.rb +237 -0
  24. data/lib/cuken/chef.rb +2 -0
  25. data/lib/cuken/common.rb +1 -0
  26. data/lib/cuken/cucumber/chef/common.rb +4 -2
  27. data/lib/cuken/cucumber/chef/cookbook.rb +87 -12
  28. data/lib/cuken/cucumber/chef/data_bag.rb +27 -0
  29. data/lib/cuken/cucumber/chef/knife.rb +10 -0
  30. data/lib/cuken/cucumber/chef/node.rb +20 -8
  31. data/lib/cuken/cucumber/chef/role.rb +18 -1
  32. data/lib/cuken/cucumber/chef.rb +5 -3
  33. data/lib/cuken/cucumber/cmd.rb +1 -1
  34. data/lib/cuken/cucumber/file.rb +18 -2
  35. data/lib/cuken/cucumber/rvm.rb +4 -0
  36. data/lib/cuken/rvm.rb +3 -0
  37. data/spec/api/knife_spec.rb +94 -0
  38. data/spec/api/rvm_spec.rb +274 -0
  39. data/spec/api/rvmrc_processor_spec.rb +288 -0
  40. data/spec/spec_helper.rb +58 -2
  41. metadata +67 -30
@@ -3,15 +3,37 @@ module ::Cuken
3
3
  module Chef
4
4
  module Common
5
5
 
6
- include Grit
6
+ include ::Grit
7
+ ::Grit.debug = true
7
8
 
8
- attr_accessor :recipe, :cookbook, :api_response, :inflated_response, :log_level,
9
- :chef_args, :config_file, :stdout, :stderr, :status, :exception,
10
- :gemserver_thread, :sandbox_url,
11
- :uri, :client_private_key_path, :admin_client_name,
12
- :client_name, :client_knife_path, :cookbook_paths, :cookbooks_paths,
13
- :knife_debug, :local_cookbook_repo, :remote_cookbook_repo,
14
- :local_chef_repo, :remote_chef_repo
9
+ attr_accessor :admin_client_name,
10
+ :api_response,
11
+ :exception,
12
+ :chef_args,
13
+ :client_knife_path,
14
+ :client_name,
15
+ :client_private_key_path,
16
+ :config_file,
17
+ :cookbook,
18
+ :cookbook_paths,
19
+ :cookbooks_paths,
20
+ :cookbooks_uri,
21
+ :knife_debug,
22
+ :gemserver_thread,
23
+ :inflated_response,
24
+ :local_chef_repo,
25
+ :local_cookbook_repo,
26
+ :local_site_cookbook_repo,
27
+ :log_level,
28
+ :recipe,
29
+ :remote_chef_repo,
30
+ :remote_cookbook_repo,
31
+ :root_dir,
32
+ :sandbox_url,
33
+ :status,
34
+ :stderr,
35
+ :stdout,
36
+ :uri
15
37
 
16
38
  def self.ohai
17
39
  # ohai takes a while, so only ever run it once.
@@ -34,7 +56,15 @@ module ::Cuken
34
56
  @chef ||= self
35
57
  end
36
58
 
59
+ def in_chef_root(&block)
60
+ ::Dir.chdir(chef.root_dir, &block)
61
+ end
62
+
37
63
  def knife
64
+ ::Cuken::Api::Chef::Knife.new
65
+ end
66
+
67
+ def knife_command
38
68
  'knife '
39
69
  end
40
70
 
@@ -50,6 +80,14 @@ module ::Cuken
50
80
  end
51
81
  end
52
82
 
83
+ def root_dir
84
+ @root_dir ||= Pathname.getwd
85
+ end
86
+
87
+ def config_file
88
+ @config_file ||= (chef.root_dir + '/.chef/knife.rb')
89
+ end
90
+
53
91
  def make_admin
54
92
  admin_client
55
93
  @rest = ::Chef::REST.new(Chef::Config[:registration_url], 'bobo', "#{tmpdir}/bobo.pem")
@@ -0,0 +1,107 @@
1
+ require 'chef/application/knife'
2
+
3
+ module ::Cuken
4
+ module Api
5
+ module Chef
6
+ module Knife
7
+
8
+ include ::Cuken::Api::Common
9
+
10
+ class CliTemplate
11
+ include Mixlib::CLI
12
+ end
13
+
14
+ # Ripped from Grit: https://github.com/mojombo/grit
15
+
16
+ class CommandTimeout < RuntimeError
17
+ attr_accessor :command
18
+ attr_accessor :bytes_read
19
+
20
+ def initialize(command = nil, bytes_read = nil)
21
+ @command = command
22
+ @bytes_read = bytes_read
23
+ end
24
+ end
25
+
26
+ # Raised when a command exits with non-zero.
27
+ class CommandFailed < StandardError
28
+ # The full command that failed as a String.
29
+ attr_reader :command
30
+
31
+ # The integer exit status.
32
+ attr_reader :exitstatus
33
+
34
+ # Everything output on the command's stderr as a String.
35
+ attr_reader :err
36
+
37
+ def initialize(command, exitstatus=nil, err='')
38
+ if exitstatus
39
+ @command = command
40
+ @exitstatus = exitstatus
41
+ @err = err
42
+ message = "Command failed [#{exitstatus}]: #{command}"
43
+ message << "\n\n" << err unless err.nil? || err.empty?
44
+ super message
45
+ else
46
+ super command
47
+ end
48
+ end
49
+ end
50
+
51
+
52
+ def set_cli_options_template(data)
53
+ conf = data[:config]||'/etc/chef/knife.rb'
54
+ CliTemplate.option(:config_file, :long => '--config CONFIG', :default => conf)
55
+ CliTemplate.option(:no_editor, :long => "--no-editor", :boolean => true, :default => true)
56
+ CliTemplate.option(:yes, :long => "--yes", :boolean => true, :default => true)
57
+ end
58
+
59
+ def create_client(client_name)
60
+ chef.client_private_key_path = chef.root_dir + "/.chef/#{client_name}.pem"
61
+ data = {:name => client_name,
62
+ :admin => true,
63
+ :file => chef.client_private_key_path,
64
+ :no_editor => true,
65
+ :config_file => chef.config_file}
66
+ argv = ['client', 'create', data[:name], '--file', data[:file], '--config', data[:config_file],'--no-editor']
67
+ argv << '--admin' if data[:admin]
68
+ unless Pathname(chef.client_private_key_path).exist?
69
+ with_args *argv do
70
+ ::Chef::Application::Knife.new.run # (args, CliTemplate.options)
71
+ end
72
+ else
73
+ #TODO: Verify client exists on the Chef server, and has matching public key.
74
+ end
75
+ end
76
+
77
+ def show_client(client_name)
78
+ chef.client_private_key_path = chef.root_dir + "/.chef/#{client_name}.pem"
79
+ data = {:name => client_name,
80
+ :config_file => chef.config_file}
81
+ argv = ['client', 'show', data[:name], '--config', data[:config_file],'--no-editor']
82
+ argv << '--admin' if data[:admin]
83
+ with_args *argv do
84
+ ::Chef::Application::Knife.new.run # (args, CliTemplate.options)
85
+ end
86
+ end
87
+
88
+ def delete_client(client_name)
89
+ chef.client_private_key_path = chef.root_dir + "/.chef/#{client_name}.pem"
90
+ data = {:name => client_name,
91
+ :file => chef.client_private_key_path,
92
+ :no_editor => true,
93
+ :yes => true,
94
+ :print_after => true,
95
+ :config_file => chef.config_file}
96
+ argv = ['client', 'delete', data[:name], '--no-editor', '--yes' ]
97
+ with_args *argv do
98
+ ::Chef::Application::Knife.new.run
99
+ end
100
+ end
101
+
102
+ end # class knife
103
+
104
+ end # module Chef
105
+ end # module Api
106
+ end # module Cuken
107
+
@@ -1,6 +1,9 @@
1
1
  require 'aruba/api' unless defined? Aruba::Api
2
2
  require 'chef' unless defined? Chef
3
+ require 'grit' unless defined? Grit
4
+ require 'cuken/api/common'
3
5
  require 'cuken/api/chef/common'
6
+ require 'cuken/api/chef/knife'
4
7
 
5
8
  module ::Cuken
6
9
  module Api
@@ -39,22 +42,24 @@ module ::Cuken
39
42
 
40
43
  def chef_clone_repo(ckbk_path, cookbook = false, repo = chef.remote_chef_repo, brnch = 'master')
41
44
  in_current_dir do
45
+ pth = Pathname(ckbk_path).expand_path
42
46
  gritty = ::Grit::Git.new(current_dir)
47
+ $stdout.puts gritty.inspect
43
48
  clone_opts = {:quiet => false, :verbose => true, :progress => true, :branch => brnch}
44
- if Dir.exists?(ckbk_path)
45
- $stdout.puts "Pulling: #{repo} into #{ckbk_path}"
46
- gritty.pull(clone_opts, repo, ckbk_path)
49
+ if pth.directory?
50
+ $stdout.puts "Pulling: #{repo} into #{pth}"
51
+ gritty.pull(clone_opts, repo, pth.to_s)
47
52
  else
48
- $stdout.puts "Cloning: #{repo} into #{ckbk_path}"
49
- gritty.clone(clone_opts, repo, ckbk_path)
53
+ $stdout.puts "Cloning: #{repo} into #{pth}"
54
+ res = gritty.clone(clone_opts, repo, pth.to_s)
50
55
  end
51
- update_cookbook_paths(ckbk_path, cookbook)
52
- Pathname(ckbk_path)
56
+ update_cookbook_paths(pth, cookbook)
57
+ pth
53
58
  end
54
59
  end
55
60
 
56
61
  def run_knife_command(cmd, interactive=false)
57
- no_ckbk_pth_opt = ['cookbook delete'].each{|str| break true if cmd[/#{str}/]}
62
+ no_ckbk_pth_opt = ['cookbook delete', 'role from file'].each{|str| break true if cmd[/#{str}/]}
58
63
  no_ckbk_pth = chef.cookbooks_paths.empty?
59
64
  if no_ckbk_pth
60
65
  ckbk_pth_opt = false
@@ -68,13 +73,16 @@ module ::Cuken
68
73
  chef.client_knife_path = Pathname(chef.local_chef_repo).ascend { |d| h=d+'.chef'+'knife.rb'; break h if h.file? }
69
74
  end
70
75
  raise(RuntimeError, "chef.client_knife_path is required", caller) unless chef.client_knife_path
71
- cmd += " -c #{chef.client_knife_path.expand_path.to_s}" if chef.client_knife_path.expand_path.exist?
72
- cmd += " -o #{ckbk_pth}" if ckbk_pth_opt
73
- cmd += " --log_level debug" if chef.knife_debug
76
+ end
77
+ cmd += " -c #{chef.client_knife_path.expand_path.to_s}" if chef.client_knife_path.expand_path.exist?
78
+ cmd += " -o #{ckbk_pth}" if ckbk_pth_opt
79
+ cmd += " --log_level debug" if chef.knife_debug
80
+ chef.root_dir ||= current_dir
81
+ in_chef_root do
74
82
  if interactive
75
- run_interactive(unescape("#{chef.knife}" + cmd))
83
+ run_interactive(unescape("#{chef.knife_command}" + cmd))
76
84
  else
77
- run_simple(unescape("#{chef.knife}" + cmd))
85
+ run_simple(unescape("#{chef.knife_command}" + cmd))
78
86
  end
79
87
  end
80
88
  end
@@ -4,6 +4,18 @@ module ::Cuken
4
4
  module Api
5
5
  module Common
6
6
 
7
+ def with_args(*args)
8
+ backup = ARGV.dup
9
+ begin
10
+ ARGV.replace(args)
11
+ yield
12
+ rescue Exception => e
13
+ puts e.backtrace.join("\n") if $!.respond_to?(:status) && $!.status && $!.status > 0
14
+ ensure
15
+ ARGV.replace(backup)
16
+ end
17
+ end
18
+
7
19
  end
8
20
  end
9
21
  end