cuken 0.1.4 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.relish +2 -0
- data/Gemfile +4 -4
- data/Gemfile.lock +17 -23
- data/VERSION +1 -1
- data/cuken.gems +108 -0
- data/cuken.gemspec +33 -10
- data/features/about.md +15 -2
- data/features/chef_examples/cookbooks_cookbook.feature +38 -3
- data/features/chef_examples/cookbooks_remote_repo.feature +10 -0
- data/features/chef_examples/cookbooks_repo.feature +5 -5
- data/features/{chef_steps → chef_examples}/knife_admin_client.feature +4 -4
- data/features/chef_examples/knife_client_create.feature +13 -0
- data/features/chef_steps/common_steps.feature +2 -2
- data/features/chef_steps/cookbook_steps.feature +12 -5
- data/features/chef_steps/node_steps.feature +1 -1
- data/features/file_steps/file_steps.feature +11 -11
- data/lib/cuken/all.rb +4 -0
- data/lib/cuken/api/chef/common.rb +46 -8
- data/lib/cuken/api/chef/knife.rb +107 -0
- data/lib/cuken/api/chef.rb +21 -13
- data/lib/cuken/api/common.rb +12 -0
- data/lib/cuken/api/rvm.rb +501 -0
- data/lib/cuken/api/ssh-forever.rb +237 -0
- data/lib/cuken/chef.rb +2 -0
- data/lib/cuken/common.rb +1 -0
- data/lib/cuken/cucumber/chef/common.rb +4 -2
- data/lib/cuken/cucumber/chef/cookbook.rb +87 -12
- data/lib/cuken/cucumber/chef/data_bag.rb +27 -0
- data/lib/cuken/cucumber/chef/knife.rb +10 -0
- data/lib/cuken/cucumber/chef/node.rb +20 -8
- data/lib/cuken/cucumber/chef/role.rb +18 -1
- data/lib/cuken/cucumber/chef.rb +5 -3
- data/lib/cuken/cucumber/cmd.rb +1 -1
- data/lib/cuken/cucumber/file.rb +18 -2
- data/lib/cuken/cucumber/rvm.rb +4 -0
- data/lib/cuken/rvm.rb +3 -0
- data/spec/api/knife_spec.rb +94 -0
- data/spec/api/rvm_spec.rb +274 -0
- data/spec/api/rvmrc_processor_spec.rb +288 -0
- data/spec/spec_helper.rb +58 -2
- 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 :
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
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
|
+
|
data/lib/cuken/api/chef.rb
CHANGED
@@ -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
|
45
|
-
$stdout.puts "Pulling: #{repo} into #{
|
46
|
-
gritty.pull(clone_opts, repo,
|
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 #{
|
49
|
-
gritty.clone(clone_opts, repo,
|
53
|
+
$stdout.puts "Cloning: #{repo} into #{pth}"
|
54
|
+
res = gritty.clone(clone_opts, repo, pth.to_s)
|
50
55
|
end
|
51
|
-
update_cookbook_paths(
|
52
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
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.
|
83
|
+
run_interactive(unescape("#{chef.knife_command}" + cmd))
|
76
84
|
else
|
77
|
-
run_simple(unescape("#{chef.
|
85
|
+
run_simple(unescape("#{chef.knife_command}" + cmd))
|
78
86
|
end
|
79
87
|
end
|
80
88
|
end
|
data/lib/cuken/api/common.rb
CHANGED
@@ -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
|