knife-sharp 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -94,6 +94,38 @@ Available servers:
94
94
  dev (/home/jamiez/.chef/knife-dev.rb)
95
95
  </pre>
96
96
 
97
+ ## Rollback
98
+
99
+ Sometimes you need to be able to rollback a change quickly, because failure happens. So knife sharp now creates rollback points of environment constraints.
100
+
101
+ A picture says a thousand words :
102
+
103
+ <pre>
104
+ $ knife sharp rollback --list
105
+ Available rollback points :
106
+ * 1370414322 (Wed Jun 05 08:38:42 +0200 2013)
107
+ * 1370418655 (Wed Jun 05 09:50:55 +0200 2013)
108
+ * 1370419966 (Wed Jun 05 10:12:46 +0200 2013)
109
+ * 1370421569 (Wed Jun 05 10:39:29 +0200 2013)
110
+ $ knife sharp rollback --show 1370421569
111
+ Rollback point has the following informations :
112
+ environment : production
113
+ cookbooks versions :
114
+ * tests => = 0.0.2
115
+ * varnish => = 0.0.10
116
+ $ knife sharp rollback --to 1370421569
117
+ Rollback point has the following informations :
118
+ environment : production
119
+ cookbooks versions :
120
+ * varnish => = 0.0.10
121
+ * tests => = 0.0.2
122
+ Continue rollback ? Y/(N) [N] y
123
+ Setting varnish to version = 0.0.10
124
+ Setting tests to version = 0.0.2
125
+ </pre>
126
+
127
+ The activation of this rollback feature and its storage dir can be configured in your sharp-config.yml file.
128
+
97
129
  # Configuration
98
130
 
99
131
  Dependencies :
@@ -127,6 +159,17 @@ logging:
127
159
 
128
160
  It will log uploads, bumps and databags to the standard logger format.
129
161
 
162
+ # ZSH completion
163
+
164
+ want a completion on changing servers ?
165
+
166
+ <pre>
167
+ alias kss="knife sharp server"
168
+
169
+ function knife_servers { reply=($(ls .chef/knife-*.rb | sed -r 's/.*knife-([a-zA-Z0-9]+)\.rb/\1/' )); }
170
+ compctl -K knife_servers kss
171
+ </pre>
172
+
130
173
  # Credits
131
174
 
132
175
  The damn good knife spork plugin from the etsy folks : https://github.com/jonlives/knife-spork
@@ -139,5 +182,5 @@ License
139
182
 
140
183
  Authors
141
184
  ======
142
- Nicolas Szalay | https://github.com/rottenbytes
143
- Jonathan Amiez | https://github.com/josqu4red
185
+ * Nicolas Szalay | https://github.com/rottenbytes
186
+ * Jonathan Amiez | https://github.com/josqu4red
data/ext/sharp-config.yml CHANGED
@@ -14,3 +14,6 @@ notification:
14
14
  # key is the name of your server (in a knife sharp server sense)
15
15
  sandboxnico:
16
16
  ignore_cookbooks: [ "tests" ]
17
+ rollback:
18
+ enabled: true
19
+ destination: "/home/nico/.chef/sharp/rollbacks/"
@@ -8,7 +8,7 @@ module KnifeSharp
8
8
 
9
9
  [:cookbooks, :databags, :roles].each do |opt|
10
10
  option opt,
11
- :short => "-#{opt.to_s[0].upcase}",
11
+ :short => "-#{opt.to_s[0,1].upcase}",
12
12
  :long => "--#{opt}-only",
13
13
  :description => "sync #{opt} only",
14
14
  :default => false
@@ -187,8 +187,14 @@ module KnifeSharp
187
187
  unless @cookbooks.empty?
188
188
  env = Chef::Environment.load(@environment)
189
189
  cbs = Array.new
190
+ backup_data = Hash.new
191
+ backup_data["environment"] = @environment
192
+ backup_data["cookbook_versions"] = Hash.new
190
193
  @cookbooks.each do |cb_name|
191
194
  cb = @loader[cb_name]
195
+ if @cfg["rollback"]["enabled"] == true
196
+ backup_data["cookbook_versions"][cb_name] = env.cookbook_versions[cb_name]
197
+ end
192
198
  # Force "= a.b.c" in cookbook version, as chef11 will not accept "a.b.c"
193
199
  env.cookbook_versions[cb_name] = "= #{cb.version}"
194
200
  cbs << cb
@@ -204,6 +210,14 @@ module KnifeSharp
204
210
  log_action("bumping #{cb.name} to #{cb.version} for environment #{@environment}")
205
211
  end
206
212
  end
213
+
214
+ if @cfg["rollback"]["enabled"] == true
215
+ identifier = Time.now.to_i
216
+ Dir.mkdir(@cfg["rollback"]["destination"]) unless File.exists?(@cfg["rollback"]["destination"])
217
+ fp = open(File.join(@cfg["rollback"]["destination"], "#{identifier}.json"), "w")
218
+ fp.write(JSON.pretty_generate(backup_data))
219
+ fp.close()
220
+ end
207
221
  end
208
222
  end
209
223
 
@@ -0,0 +1,144 @@
1
+ module KnifeSharp
2
+ class SharpRollback < Chef::Knife
3
+
4
+ banner "knife sharp rollback [--list] [--to <identifier>] [--show <identifier>]"
5
+
6
+ option :list,
7
+ :short => '-l',
8
+ :long => '--list',
9
+ :description => "lists rollback points",
10
+ :default => false
11
+
12
+ option :to,
13
+ :short => "-t",
14
+ :long => "--to",
15
+ :description => "the rollback point identifier",
16
+ :default => nil
17
+
18
+ option :show,
19
+ :short => "-s",
20
+ :long => "--show",
21
+ :description => "show what the rollback point contains",
22
+ :default => false
23
+
24
+ deps do
25
+ require 'chef/cookbook/metadata'
26
+ require 'chef/cookbook_loader'
27
+ require 'chef/cookbook_uploader'
28
+ end
29
+
30
+ def run()
31
+ setup()
32
+
33
+ if config[:list]
34
+ list_rollback_points()
35
+ exit 0
36
+ end
37
+
38
+ if config[:show]
39
+ identifier = name_args
40
+ show_rollback_point(identifier)
41
+ exit 0
42
+ end
43
+
44
+ if config[:to]
45
+ identifier = name_args
46
+ rollback_to(identifier)
47
+ exit 0
48
+ end
49
+ end
50
+
51
+ def setup()
52
+ actions = 0
53
+ [:to, :list, :show].each do |action|
54
+ if config[action]
55
+ actions+=1
56
+ end
57
+ end
58
+
59
+ if actions > 1
60
+ ui.error("please specify only one action")
61
+ exit 1
62
+ end
63
+
64
+
65
+ # Sharp config
66
+ cfg_files = [ "/etc/sharp-config.yml", "~/.chef/sharp-config.yml" ]
67
+ loaded = false
68
+ cfg_files.each do |cfg_file|
69
+ begin
70
+ @cfg = YAML::load_file(File.expand_path(cfg_file))
71
+ loaded = true
72
+ rescue Exception => e
73
+ ui.error "Error on loading config : #{e.inspect}" if config[:verbosity] > 0
74
+ end
75
+ end
76
+ unless loaded == true
77
+ ui.error "config could not be loaded ! Tried the following files : #{cfg_files.join(", ")}"
78
+ exit 1
79
+ end
80
+
81
+ # Knife config
82
+ if Chef::Knife.chef_config_dir && File.exists?(File.join(Chef::Knife.chef_config_dir, "knife.rb"))
83
+ Chef::Config.from_file(File.join(Chef::Knife.chef_config_dir, "knife.rb"))
84
+ else
85
+ ui.error "Cannot find knife.rb config file"
86
+ exit 1
87
+ end
88
+
89
+ chefcfg = Chef::Config
90
+ @cb_path = chefcfg.cookbook_path.is_a?(Array) ? chefcfg.cookbook_path.first : chefcfg.cookbook_path
91
+ @loader = Chef::CookbookLoader.new(@cb_path)
92
+ end
93
+
94
+ def list_rollback_points()
95
+ ui.msg("Available rollback points :")
96
+ Dir.glob(File.join(@cfg["rollback"]["destination"], "*.json")).each do |f|
97
+ ts = File.basename(f, ".json")
98
+ ui.msg(" * #{ts} (#{Time.at(ts.to_i).to_s})")
99
+ end
100
+ exit 0
101
+ end
102
+
103
+ def rollback_to(identifier)
104
+ show_rollback_point(identifier)
105
+ answer = ui.ask_question("Continue rollback ? Y/(N) ", :default => "N").upcase
106
+ if answer != "Y"
107
+ ui.msg("Aborting !")
108
+ exit 0
109
+ end
110
+
111
+ begin
112
+ fp = File.open(File.join(@cfg["rollback"]["destination"],"#{identifier}.json"),"r")
113
+ infos = JSON.load(fp)
114
+ rescue
115
+ ui.error("could not load rollback point #{identifier}")
116
+ exit 1
117
+ end
118
+
119
+ env = Chef::Environment.load(infos["environment"])
120
+ infos["cookbook_versions"].each do |cb, version|
121
+ env.cookbook_versions[cb] = version
122
+ ui.msg("Setting #{cb} to version #{version}")
123
+ end
124
+ env.save
125
+ end
126
+
127
+ def show_rollback_point(identifier)
128
+ begin
129
+ fp = File.open(File.join(@cfg["rollback"]["destination"],"#{identifier}.json"),"r")
130
+ rescue
131
+ ui.error("could not load rollback point #{identifier}")
132
+ exit 1
133
+ end
134
+ infos = JSON.load(fp)
135
+ ui.msg("Rollback point has the following informations :")
136
+ ui.msg(" environment : #{infos["environment"]}")
137
+ ui.msg(" cookbooks versions :")
138
+ infos["cookbook_versions"].each do |cb, version|
139
+ ui.msg(" * #{cb} => #{version}")
140
+ end
141
+ end
142
+
143
+ end
144
+ end
data/lib/knife-sharp.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module KnifeSharp
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,57 +1,66 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: knife-sharp
3
- version: !ruby/object:Gem::Version
4
- version: 0.2.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Nicolas Szalay
9
14
  - Jonathan Amiez
10
15
  autorequire:
11
16
  bindir: bin
12
17
  cert_chain: []
13
- date: 2013-04-23 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
18
+
19
+ date: 2013-06-05 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
16
22
  name: chef
17
- requirement: !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ! '>='
21
- - !ruby/object:Gem::Version
22
- version: 10.14.0
23
- type: :runtime
24
23
  prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
24
+ requirement: &id001 !ruby/object:Gem::Requirement
26
25
  none: false
27
- requirements:
28
- - - ! '>='
29
- - !ruby/object:Gem::Version
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 119
30
+ segments:
31
+ - 10
32
+ - 14
33
+ - 0
30
34
  version: 10.14.0
31
- - !ruby/object:Gem::Dependency
32
- name: grit
33
- requirement: !ruby/object:Gem::Requirement
34
- none: false
35
- requirements:
36
- - - ~>
37
- - !ruby/object:Gem::Version
38
- version: 2.5.0
39
35
  type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: grit
40
39
  prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
40
+ requirement: &id002 !ruby/object:Gem::Requirement
42
41
  none: false
43
- requirements:
42
+ requirements:
44
43
  - - ~>
45
- - !ruby/object:Gem::Version
44
+ - !ruby/object:Gem::Version
45
+ hash: 27
46
+ segments:
47
+ - 2
48
+ - 5
49
+ - 0
46
50
  version: 2.5.0
51
+ type: :runtime
52
+ version_requirements: *id002
47
53
  description: Sharpen your knife
48
- email:
54
+ email:
49
55
  - nico@rottenbytes.info
50
56
  - jonathan.amiez@gmail.com
51
57
  executables: []
58
+
52
59
  extensions: []
60
+
53
61
  extra_rdoc_files: []
54
- files:
62
+
63
+ files:
55
64
  - README.md
56
65
  - ext/sharp-config.yml
57
66
  - lib/knife-sharp.rb
@@ -59,28 +68,39 @@ files:
59
68
  - lib/chef/knife/sharp-backup.rb
60
69
  - lib/chef/knife/sharp-history.rb
61
70
  - lib/chef/knife/sharp-server.rb
71
+ - lib/chef/knife/sharp-rollback.rb
62
72
  homepage: https://github.com/Fotolia/knife-sharp
63
73
  licenses: []
74
+
64
75
  post_install_message:
65
76
  rdoc_options: []
66
- require_paths:
77
+
78
+ require_paths:
67
79
  - lib
68
- required_ruby_version: !ruby/object:Gem::Requirement
80
+ required_ruby_version: !ruby/object:Gem::Requirement
69
81
  none: false
70
- requirements:
71
- - - ! '>='
72
- - !ruby/object:Gem::Version
73
- version: '0'
74
- required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
90
  none: false
76
- requirements:
77
- - - ! '>='
78
- - !ruby/object:Gem::Version
79
- version: '0'
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
80
98
  requirements: []
99
+
81
100
  rubyforge_project:
82
- rubygems_version: 1.8.25
101
+ rubygems_version: 1.8.24
83
102
  signing_key:
84
103
  specification_version: 3
85
104
  summary: Knife sharp plugin
86
105
  test_files: []
106
+