knife-spork 1.0.13 → 1.0.14

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.
@@ -1,8 +1,20 @@
1
+ ## 1.0.14 (15th January, 2013)
2
+
3
+ Features:
4
+
5
+ - Campfire plugin changed to use campy gem (thanks to Seth Vargo)
6
+ - Organization name now added to messages when present (thanks to Seth Vargo)
7
+ - Berkshelf support now added (thanks to Seth Vargo)
8
+
9
+ Bugfixes:
10
+
11
+ - Promote won't try to create a version diff if there is no existing remote version (thanks to Seth Vargo)
12
+
1
13
  ## 1.0.13 (9th January, 2013)
2
14
 
3
15
  Features:
4
16
 
5
- - Jabber Plugin (thanks to Graham McMillan - https://github.com/gmcmillan)
17
+ - Made spork promote Use environment_path from spork config if it's set( thanks to Greg Karékinian - https://github.com/gkarekinian)
6
18
 
7
19
  ## 1.0.12 (22nd November, 2012)
8
20
  Bugfixes:
@@ -2,7 +2,7 @@ $:.push File.expand_path('../lib', __FILE__)
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = 'knife-spork'
5
- gem.version = '1.0.13'
5
+ gem.version = '1.0.14'
6
6
  gem.authors = ["Jon Cowie"]
7
7
  gem.email = 'jonlives@gmail.com'
8
8
  gem.homepage = 'https://github.com/jonlives/knife-spork'
@@ -2,6 +2,10 @@ require 'chef/knife'
2
2
  require 'chef/exceptions'
3
3
  require 'knife-spork/runner'
4
4
 
5
+ begin
6
+ require 'berkshelf'
7
+ rescue LoadError; end
8
+
5
9
  module KnifeSpork
6
10
  class SporkPromote < Chef::Knife
7
11
  include KnifeSpork::Runner
@@ -19,6 +23,14 @@ module KnifeSpork
19
23
  :description => 'Save the environment to the chef server in addition to the local JSON file',
20
24
  :default => nil
21
25
 
26
+ if defined?(::Berkshelf)
27
+ option :berksfile,
28
+ :short => '-b',
29
+ :long => 'berksfile',
30
+ :description => 'Path to a Berksfile to operate off of',
31
+ :default => File.join(Dir.pwd, ::Berkshelf::DEFAULT_FILENAME)
32
+ end
33
+
22
34
  def run
23
35
  self.config = Chef::Config.merge!(config)
24
36
 
@@ -77,10 +89,10 @@ module KnifeSpork
77
89
  remote_environment = load_remote_environment(environment)
78
90
  @environment_diffs ||= Hash.new
79
91
  @environment_diffs["#{environment}"] = environment_diff(local_environment, remote_environment)
80
-
92
+
81
93
  version_change_threshold = spork_config.version_change_threshold || 2
82
94
  env_constraints_diff = constraints_diff(@environment_diffs["#{environment}"]).select{|k,v| v > version_change_threshold}
83
-
95
+
84
96
  if env_constraints_diff.size !=0 then
85
97
  ui.warn 'You\'re about to promote a significant version number change to 1 or more cookbooks:'
86
98
  ui.warn @environment_diffs["#{environment}"].select{|k,v|env_constraints_diff.has_key?(k)}.collect{|k,v| "\t#{k}: #{v}"}.join("\n")
@@ -98,8 +110,8 @@ module KnifeSpork
98
110
  raise
99
111
  end
100
112
  end
101
-
102
- if @environment_diffs["#{environment}"].size > 1
113
+
114
+ if @environment_diffs["#{environment}"].size > 1
103
115
  ui.msg ""
104
116
  ui.warn "You're about to promote changes to several cookbooks at once:"
105
117
  ui.warn @environment_diffs["#{environment}"].collect{|k,v| "\t#{k}: #{v}"}.join("\n")
@@ -10,7 +10,7 @@ module KnifeSpork
10
10
  def after_upload
11
11
  campfire do |rooms|
12
12
  rooms.paste <<-EOH
13
- #{current_user} froze the following cookbooks on Chef Server:
13
+ #{organization}#{current_user} froze the following cookbooks on Chef Server:
14
14
  #{cookbooks.collect{|c| " #{c.name}@#{c.version}"}.join("\n")}
15
15
  EOH
16
16
  end
@@ -19,7 +19,7 @@ EOH
19
19
  def after_promote_remote
20
20
  campfire do |rooms|
21
21
  rooms.paste <<-EOH
22
- #{current_user} promoted cookbooks on Chef Server:
22
+ #{organization}#{current_user} promoted cookbooks on Chef Server:
23
23
 
24
24
  cookbooks:
25
25
  #{cookbooks.collect{|c| " #{c.name}@#{c.version}"}.join("\n")}
@@ -32,13 +32,17 @@ EOH
32
32
 
33
33
  private
34
34
  def campfire(&block)
35
- safe_require 'tinder'
35
+ safe_require 'campy'
36
36
 
37
37
  rooms = [config.rooms || config.room].flatten.compact
38
- campfire = Tinder::Campfire.new(config.account, :token => config.token)
38
+ campfire = Campy::Room.new(:account => config.account, :token => config.token)
39
39
 
40
40
  rooms.each do |room_name|
41
- room = campfire.find_room_by_name(room_name)
41
+ room = Campy::Room.new(
42
+ :account => config.account,
43
+ :token => config.token,
44
+ :room => room_name
45
+ )
42
46
  yield(room) unless room.nil?
43
47
  end
44
48
  end
@@ -14,7 +14,7 @@ module KnifeSpork
14
14
  event_data = {
15
15
  :tag => 'knife',
16
16
  :username => current_user,
17
- :status => "#{current_user} has uploaded and frozen #{cookbook.name}@#{cookbook.version}",
17
+ :status => "#{organization}#{current_user} uploaded and froze #{cookbook.name}@#{cookbook.version}",
18
18
  :metadata => {
19
19
  :cookbook_name => cookbook.name,
20
20
  :cookbook_version => cookbook.version
@@ -30,7 +30,7 @@ module KnifeSpork
30
30
  event_data = {
31
31
  :tag => 'knife',
32
32
  :username => current_user,
33
- :status => "#{current_user} has promoted #{cookbook.name}(#{cookbook.version}) to #{environment.name}",
33
+ :status => "#{organization}#{current_user} promoted #{cookbook.name}(#{cookbook.version}) to #{environment.name}",
34
34
  :metadata => {
35
35
  :cookbook_name => cookbook.name,
36
36
  :cookbook_version => cookbook.version
@@ -8,11 +8,11 @@ module KnifeSpork
8
8
  def perform; end
9
9
 
10
10
  def after_upload
11
- hipchat "#{current_user} uploaded the following cookbooks:\n#{cookbooks.collect{ |c| " #{c.name}@#{c.version}" }.join("\n")}"
11
+ hipchat "#{organization}#{current_user} uploaded the following cookbooks:\n#{cookbooks.collect{ |c| " #{c.name}@#{c.version}" }.join("\n")}"
12
12
  end
13
13
 
14
14
  def after_promote_remote
15
- hipchat "#{current_user} promoted the following cookbooks:\n#{cookbooks.collect{ |c| " #{c.name}@#{c.version}" }.join("\n")} to #{environments.collect{ |e| "#{e.name}" }.join(", ")}"
15
+ hipchat "#{organization}#{current_user} promoted the following cookbooks:\n#{cookbooks.collect{ |c| " #{c.name}@#{c.version}" }.join("\n")} to #{environments.collect{ |e| "#{e.name}" }.join(", ")}"
16
16
  end
17
17
 
18
18
  private
@@ -8,14 +8,14 @@ module KnifeSpork
8
8
  def perform; end
9
9
 
10
10
  def after_upload
11
- irccat("#BOLD#PURPLECHEF:#NORMAL #{current_user} uploaded #TEAL#{cookbooks.collect{ |c| "#{c.name}@#{c.version}" }.join(", ")}#NORMAL")
11
+ irccat("#BOLD#PURPLECHEF:#NORMAL #{organization}#{current_user} uploaded #TEAL#{cookbooks.collect{ |c| "#{c.name}@#{c.version}" }.join(", ")}#NORMAL")
12
12
  end
13
13
 
14
14
  def after_promote_remote
15
15
  environments.each do |environment|
16
16
  diff = environment_diffs[environment.name]
17
17
  env_gist = gist(environment, diff) if config.gist
18
- irccat("#BOLD#PURPLECHEF:#NORMAL #{current_user} promoted #TEAL#{cookbooks.collect{ |c| "#{c.name}@#{c.version}" }.join(", ")}#NORMAL to #{environment.name} #{env_gist}")
18
+ irccat("#BOLD#PURPLECHEF:#NORMAL #{organization}#{current_user} promoted #TEAL#{cookbooks.collect{ |c| "#{c.name}@#{c.version}" }.join(", ")}#NORMAL to #{environment.name} #{env_gist}")
19
19
  end
20
20
  end
21
21
 
@@ -39,7 +39,7 @@ module KnifeSpork
39
39
  msg = "Environment #{environment} uploaded at #{Time.now.getutc} by #{current_user}\n\nConstraints updated on server in this version:\n\n#{diff.collect { |k, v| "#{k}: #{v}\n" }.join}"
40
40
  %x[ echo "#{msg}" | #{config.gist}]
41
41
  end
42
-
42
+
43
43
  def channels
44
44
  [ config.channel || config.channels ].flatten
45
45
  end
@@ -8,11 +8,11 @@ module KnifeSpork
8
8
  def perform; end
9
9
 
10
10
  def after_upload
11
- jabber "#{current_user} uploaded the following cookbooks:\n#{cookbooks.collect{ |c| " #{c.name}@#{c.version}" }.join("\n")}"
11
+ jabber "#{organization}#{current_user} uploaded the following cookbooks:\n#{cookbooks.collect{ |c| " #{c.name}@#{c.version}" }.join("\n")}"
12
12
  end
13
13
 
14
14
  def after_promote_remote
15
- jabber "#{current_user} promoted the following cookbooks:\n#{cookbooks.collect{ |c| " #{c.name}@#{c.version}" }.join("\n")} to #{environments.collect{ |e| "#{e.name}" }.join(", ")}"
15
+ jabber "#{organization}#{current_user} promoted the following cookbooks:\n#{cookbooks.collect{ |c| " #{c.name}@#{c.version}" }.join("\n")} to #{environments.collect{ |e| "#{e.name}" }.join(", ")}"
16
16
  end
17
17
 
18
18
  private
@@ -37,7 +37,18 @@ module KnifeSpork
37
37
 
38
38
  private
39
39
  def config
40
- @options[:config].plugins.send(self.class.name.to_sym) unless @options[:config].nil? || @options[:config].plugins.nil?
40
+ @options[:config].plugins.send(self.class.name.to_sym) unless @options[:config].nil? || @options[:config].plugins.nil?
41
+ end
42
+
43
+ def organization
44
+ unless ::Chef::Config.chef_server_url.nil?
45
+ split_server_url = Chef::Config.chef_server_url.gsub(/http(s)?:\/\//,"").split('/')
46
+ if split_server_url.length > 1
47
+ return "#{split_server_url.last}: "
48
+ end
49
+ end
50
+
51
+ nil
41
52
  end
42
53
 
43
54
  def cookbooks
@@ -55,11 +66,11 @@ module KnifeSpork
55
66
  def environment_path
56
67
  @options[:environment_path]
57
68
  end
58
-
69
+
59
70
  def cookbook_path
60
71
  @options[:cookbook_path]
61
72
  end
62
-
73
+
63
74
  def ui
64
75
  @options[:ui]
65
76
  end
@@ -28,7 +28,7 @@ module KnifeSpork
28
28
  cookbooks = [ @cookbooks || @cookbook ].flatten.compact.collect{|cookbook| cookbook.is_a?(::Chef::CookbookVersion) ? cookbook : load_cookbook(cookbook)}.sort{|a,b| a.name.to_s <=> b.name.to_s}
29
29
  environments = [ @environments || @environment ].flatten.compact.collect{|environment| environment.is_a?(::Chef::Environment) ? environment : load_environment(environment)}.sort{|a,b| a.name.to_s <=> b.name.to_s}
30
30
  environment_diffs = @environment_diffs
31
-
31
+
32
32
  KnifeSpork::Plugins.run(
33
33
  :config => spork_config,
34
34
  :hook => hook.to_sym,
@@ -89,7 +89,7 @@ module KnifeSpork
89
89
  ensure_cookbook_path!
90
90
  [config[:cookbook_path] ||= ::Chef::Config.cookbook_path].flatten[0]
91
91
  end
92
-
92
+
93
93
  def environment_path
94
94
  spork_config[:environment_path] || cookbook_path.gsub("/cookbooks","/environments")
95
95
  end
@@ -100,8 +100,24 @@ module KnifeSpork
100
100
 
101
101
  def load_cookbook(cookbook_name)
102
102
  return cookbook_name if cookbook_name.is_a?(::Chef::CookbookVersion)
103
+
104
+ # Search the local chef repo first
103
105
  loader = ::Chef::CookbookLoader.new(Chef::Config.cookbook_path)
104
- loader[cookbook_name]
106
+ if loader.has_key?(cookbook_name)
107
+ return loader[cookbook_name]
108
+ end
109
+
110
+ # We didn't find the cookbook in our local repo, so check Berkshelf
111
+ if defined?(::Berkshelf)
112
+ berksfile = ::Berkshelf::Berksfile.from_file(self.config[:berksfile])
113
+ if cookbook = berksfile.sources.find{ |source| source.name == cookbook_name }
114
+ return cookbook
115
+ end
116
+ end
117
+
118
+ # TODO: add librarian support here
119
+
120
+ raise ::Chef::Exceptions::CookbookNotFound, "Could not find cookbook '#{cookbook_name}' in any of the sources!"
105
121
  end
106
122
 
107
123
  def load_cookbooks(cookbook_names)
@@ -119,21 +135,27 @@ module KnifeSpork
119
135
  rescue Net::HTTPServerException => e
120
136
  ui.error "Could not load #{environment_name} from Chef Server. You must upload the environment manually the first time."
121
137
  exit(1)
122
- end
138
+ end
123
139
  end
124
140
 
125
- def environment_diff (local_environment, remote_environment)
126
- local_environment_versions = local_environment.to_hash['cookbook_versions']
127
- remote_environment_versions = remote_environment.to_hash['cookbook_versions']
128
- remote_environment_versions.diff(local_environment_versions)
141
+ def environment_diff(local_environment, remote_environment)
142
+ local_environment_versions = local_environment.to_hash['cookbook_versions']
143
+ remote_environment_versions = remote_environment.to_hash['cookbook_versions']
144
+ remote_environment_versions.diff(local_environment_versions)
129
145
  end
130
-
146
+
131
147
  def constraints_diff (environment_diff)
132
- Hash[Hash[environment_diff.map{|k,v| [k, v.split(" changed to ").map{|x|x.gsub("= ","")}]}].map{|k,v|[k,calc_diff(v)]}]
148
+ Hash[Hash[environment_diff.map{|k,v| [k, v.split(" changed to ").map{|x|x.gsub("= ","")}]}].map{|k,v|[k,calc_diff(k,v)]}]
133
149
  end
134
-
135
- def calc_diff(version)
150
+
151
+ def calc_diff(cookbook, version)
136
152
  components = version.map{|v|v.split(".")}
153
+
154
+ if components.length < 2
155
+ ui.warn "#{cookbook} has no remote version to diff against!"
156
+ return 0
157
+ end
158
+
137
159
  if components[1][0].to_i != components[0][0].to_i
138
160
  return (components[1][0].to_i - components[0][0].to_i)*100
139
161
  elsif components[1][1].to_i != components[0][1].to_i
@@ -142,7 +164,7 @@ module KnifeSpork
142
164
  return (components[1][2].to_i - components[0][2].to_i)
143
165
  end
144
166
  end
145
-
167
+
146
168
  def ensure_cookbook_path!
147
169
  if !config.has_key?(:cookbook_path)
148
170
  ui.fatal "No default cookbook_path; Specify with -o or fix your knife.rb."
@@ -7,7 +7,7 @@ Gem Requirements
7
7
  This plugin requires the following gems:
8
8
 
9
9
  ```ruby
10
- gem 'tinder'
10
+ gem 'campy'
11
11
  ```
12
12
 
13
13
  Hooks
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-spork
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.13
4
+ version: 1.0.14
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-09 00:00:00.000000000 Z
12
+ date: 2013-01-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef