runa-chef 0.8.0.1

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 (216) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +136 -0
  3. data/bin/chef-client +26 -0
  4. data/bin/chef-solo +26 -0
  5. data/bin/knife +27 -0
  6. data/bin/shef +45 -0
  7. data/distro/README +2 -0
  8. data/distro/common/man/man1/chef-indexer.1 +42 -0
  9. data/distro/common/man/man1/chef-server.1 +108 -0
  10. data/distro/common/man/man8/chef-client.8 +61 -0
  11. data/distro/common/man/man8/chef-solo.8 +58 -0
  12. data/distro/common/man/man8/knife.8 +359 -0
  13. data/distro/debian/etc/init.d/chef-client +175 -0
  14. data/distro/debian/etc/init.d/chef-indexer +175 -0
  15. data/distro/debian/etc/init.d/chef-server +120 -0
  16. data/distro/redhat/etc/init.d/chef-client +78 -0
  17. data/distro/redhat/etc/init.d/chef-indexer +76 -0
  18. data/distro/redhat/etc/init.d/chef-server +78 -0
  19. data/distro/redhat/etc/sysconfig/chef-client +10 -0
  20. data/distro/redhat/etc/sysconfig/chef-indexer +8 -0
  21. data/distro/redhat/etc/sysconfig/chef-server +10 -0
  22. data/distro/suse/etc/init.d/chef-client +121 -0
  23. data/lib/chef.rb +49 -0
  24. data/lib/chef/api_client.rb +269 -0
  25. data/lib/chef/application.rb +98 -0
  26. data/lib/chef/application/agent.rb +18 -0
  27. data/lib/chef/application/client.rb +214 -0
  28. data/lib/chef/application/knife.rb +138 -0
  29. data/lib/chef/application/server.rb +19 -0
  30. data/lib/chef/application/solo.rb +214 -0
  31. data/lib/chef/cache.rb +61 -0
  32. data/lib/chef/cache/checksum.rb +70 -0
  33. data/lib/chef/certificate.rb +154 -0
  34. data/lib/chef/client.rb +323 -0
  35. data/lib/chef/compile.rb +158 -0
  36. data/lib/chef/config.rb +195 -0
  37. data/lib/chef/cookbook.rb +198 -0
  38. data/lib/chef/cookbook/metadata.rb +487 -0
  39. data/lib/chef/cookbook/metadata/version.rb +87 -0
  40. data/lib/chef/cookbook_loader.rb +180 -0
  41. data/lib/chef/couchdb.rb +273 -0
  42. data/lib/chef/daemon.rb +170 -0
  43. data/lib/chef/data_bag.rb +216 -0
  44. data/lib/chef/data_bag_item.rb +227 -0
  45. data/lib/chef/exceptions.rb +39 -0
  46. data/lib/chef/file_cache.rb +205 -0
  47. data/lib/chef/knife.rb +300 -0
  48. data/lib/chef/knife/client_bulk_delete.rb +41 -0
  49. data/lib/chef/knife/client_create.rb +55 -0
  50. data/lib/chef/knife/client_delete.rb +37 -0
  51. data/lib/chef/knife/client_edit.rb +37 -0
  52. data/lib/chef/knife/client_list.rb +40 -0
  53. data/lib/chef/knife/client_reregister.rb +48 -0
  54. data/lib/chef/knife/client_show.rb +42 -0
  55. data/lib/chef/knife/configure.rb +84 -0
  56. data/lib/chef/knife/cookbook_bulk_delete.rb +47 -0
  57. data/lib/chef/knife/cookbook_delete.rb +41 -0
  58. data/lib/chef/knife/cookbook_download.rb +57 -0
  59. data/lib/chef/knife/cookbook_list.rb +41 -0
  60. data/lib/chef/knife/cookbook_metadata.rb +87 -0
  61. data/lib/chef/knife/cookbook_show.rb +75 -0
  62. data/lib/chef/knife/cookbook_upload.rb +173 -0
  63. data/lib/chef/knife/data_bag_create.rb +43 -0
  64. data/lib/chef/knife/data_bag_delete.rb +43 -0
  65. data/lib/chef/knife/data_bag_edit.rb +49 -0
  66. data/lib/chef/knife/data_bag_list.rb +42 -0
  67. data/lib/chef/knife/data_bag_show.rb +40 -0
  68. data/lib/chef/knife/ec2_instance_data.rb +46 -0
  69. data/lib/chef/knife/node_bulk_delete.rb +44 -0
  70. data/lib/chef/knife/node_create.rb +39 -0
  71. data/lib/chef/knife/node_delete.rb +36 -0
  72. data/lib/chef/knife/node_edit.rb +36 -0
  73. data/lib/chef/knife/node_from_file.rb +42 -0
  74. data/lib/chef/knife/node_list.rb +41 -0
  75. data/lib/chef/knife/node_run_list_add.rb +64 -0
  76. data/lib/chef/knife/node_run_list_remove.rb +45 -0
  77. data/lib/chef/knife/node_show.rb +46 -0
  78. data/lib/chef/knife/role_bulk_delete.rb +45 -0
  79. data/lib/chef/knife/role_create.rb +44 -0
  80. data/lib/chef/knife/role_delete.rb +36 -0
  81. data/lib/chef/knife/role_edit.rb +37 -0
  82. data/lib/chef/knife/role_from_file.rb +46 -0
  83. data/lib/chef/knife/role_list.rb +40 -0
  84. data/lib/chef/knife/role_show.rb +43 -0
  85. data/lib/chef/knife/search.rb +94 -0
  86. data/lib/chef/log.rb +39 -0
  87. data/lib/chef/mixin/check_helper.rb +31 -0
  88. data/lib/chef/mixin/checksum.rb +32 -0
  89. data/lib/chef/mixin/command.rb +390 -0
  90. data/lib/chef/mixin/convert_to_class_name.rb +57 -0
  91. data/lib/chef/mixin/create_path.rb +56 -0
  92. data/lib/chef/mixin/deep_merge.rb +33 -0
  93. data/lib/chef/mixin/find_preferred_file.rb +92 -0
  94. data/lib/chef/mixin/from_file.rb +50 -0
  95. data/lib/chef/mixin/generate_url.rb +58 -0
  96. data/lib/chef/mixin/language.rb +107 -0
  97. data/lib/chef/mixin/language_include_attribute.rb +56 -0
  98. data/lib/chef/mixin/language_include_recipe.rb +53 -0
  99. data/lib/chef/mixin/params_validate.rb +197 -0
  100. data/lib/chef/mixin/recipe_definition_dsl_core.rb +79 -0
  101. data/lib/chef/mixin/template.rb +94 -0
  102. data/lib/chef/nanite.rb +100 -0
  103. data/lib/chef/node.rb +463 -0
  104. data/lib/chef/node/attribute.rb +412 -0
  105. data/lib/chef/openid_registration.rb +181 -0
  106. data/lib/chef/platform.rb +268 -0
  107. data/lib/chef/provider.rb +101 -0
  108. data/lib/chef/provider/breakpoint.rb +36 -0
  109. data/lib/chef/provider/cron.rb +184 -0
  110. data/lib/chef/provider/deploy.rb +314 -0
  111. data/lib/chef/provider/deploy/revision.rb +70 -0
  112. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  113. data/lib/chef/provider/directory.rb +72 -0
  114. data/lib/chef/provider/erl_call.rb +72 -0
  115. data/lib/chef/provider/execute.rb +58 -0
  116. data/lib/chef/provider/file.rb +195 -0
  117. data/lib/chef/provider/git.rb +203 -0
  118. data/lib/chef/provider/group.rb +120 -0
  119. data/lib/chef/provider/group/dscl.rb +128 -0
  120. data/lib/chef/provider/group/gpasswd.rb +50 -0
  121. data/lib/chef/provider/group/groupadd.rb +78 -0
  122. data/lib/chef/provider/group/pw.rb +88 -0
  123. data/lib/chef/provider/group/usermod.rb +57 -0
  124. data/lib/chef/provider/http_request.rb +106 -0
  125. data/lib/chef/provider/ifconfig.rb +131 -0
  126. data/lib/chef/provider/link.rb +157 -0
  127. data/lib/chef/provider/mdadm.rb +88 -0
  128. data/lib/chef/provider/mount.rb +117 -0
  129. data/lib/chef/provider/mount/mount.rb +208 -0
  130. data/lib/chef/provider/package.rb +160 -0
  131. data/lib/chef/provider/package/apt.rb +110 -0
  132. data/lib/chef/provider/package/dpkg.rb +109 -0
  133. data/lib/chef/provider/package/easy_install.rb +106 -0
  134. data/lib/chef/provider/package/freebsd.rb +153 -0
  135. data/lib/chef/provider/package/macports.rb +105 -0
  136. data/lib/chef/provider/package/portage.rb +124 -0
  137. data/lib/chef/provider/package/rpm.rb +99 -0
  138. data/lib/chef/provider/package/rubygems.rb +136 -0
  139. data/lib/chef/provider/package/yum-dump.py +125 -0
  140. data/lib/chef/provider/package/yum.rb +175 -0
  141. data/lib/chef/provider/package/zypper.rb +132 -0
  142. data/lib/chef/provider/remote_directory.rb +126 -0
  143. data/lib/chef/provider/remote_file.rb +141 -0
  144. data/lib/chef/provider/route.rb +118 -0
  145. data/lib/chef/provider/ruby_block.rb +33 -0
  146. data/lib/chef/provider/script.rb +42 -0
  147. data/lib/chef/provider/service.rb +135 -0
  148. data/lib/chef/provider/service/debian.rb +64 -0
  149. data/lib/chef/provider/service/freebsd.rb +156 -0
  150. data/lib/chef/provider/service/gentoo.rb +54 -0
  151. data/lib/chef/provider/service/init.rb +71 -0
  152. data/lib/chef/provider/service/redhat.rb +62 -0
  153. data/lib/chef/provider/service/simple.rb +114 -0
  154. data/lib/chef/provider/subversion.rb +156 -0
  155. data/lib/chef/provider/template.rb +175 -0
  156. data/lib/chef/provider/user.rb +170 -0
  157. data/lib/chef/provider/user/dscl.rb +280 -0
  158. data/lib/chef/provider/user/pw.rb +113 -0
  159. data/lib/chef/provider/user/useradd.rb +108 -0
  160. data/lib/chef/recipe.rb +105 -0
  161. data/lib/chef/resource.rb +380 -0
  162. data/lib/chef/resource/apt_package.rb +34 -0
  163. data/lib/chef/resource/bash.rb +33 -0
  164. data/lib/chef/resource/breakpoint.rb +35 -0
  165. data/lib/chef/resource/cron.rb +179 -0
  166. data/lib/chef/resource/csh.rb +33 -0
  167. data/lib/chef/resource/deploy.rb +359 -0
  168. data/lib/chef/resource/deploy_revision.rb +35 -0
  169. data/lib/chef/resource/directory.rb +76 -0
  170. data/lib/chef/resource/dpkg_package.rb +34 -0
  171. data/lib/chef/resource/easy_install_package.rb +41 -0
  172. data/lib/chef/resource/erl_call.rb +83 -0
  173. data/lib/chef/resource/execute.rb +127 -0
  174. data/lib/chef/resource/file.rb +84 -0
  175. data/lib/chef/resource/gem_package.rb +41 -0
  176. data/lib/chef/resource/git.rb +36 -0
  177. data/lib/chef/resource/group.rb +70 -0
  178. data/lib/chef/resource/http_request.rb +52 -0
  179. data/lib/chef/resource/ifconfig.rb +134 -0
  180. data/lib/chef/resource/link.rb +78 -0
  181. data/lib/chef/resource/macports_package.rb +29 -0
  182. data/lib/chef/resource/mdadm.rb +82 -0
  183. data/lib/chef/resource/mount.rb +135 -0
  184. data/lib/chef/resource/package.rb +80 -0
  185. data/lib/chef/resource/perl.rb +33 -0
  186. data/lib/chef/resource/portage_package.rb +33 -0
  187. data/lib/chef/resource/python.rb +33 -0
  188. data/lib/chef/resource/remote_directory.rb +91 -0
  189. data/lib/chef/resource/remote_file.rb +60 -0
  190. data/lib/chef/resource/route.rb +135 -0
  191. data/lib/chef/resource/ruby.rb +33 -0
  192. data/lib/chef/resource/ruby_block.rb +39 -0
  193. data/lib/chef/resource/scm.rb +137 -0
  194. data/lib/chef/resource/script.rb +51 -0
  195. data/lib/chef/resource/service.rb +134 -0
  196. data/lib/chef/resource/subversion.rb +34 -0
  197. data/lib/chef/resource/template.rb +60 -0
  198. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  199. data/lib/chef/resource/user.rb +101 -0
  200. data/lib/chef/resource_collection.rb +212 -0
  201. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  202. data/lib/chef/resource_definition.rb +67 -0
  203. data/lib/chef/rest.rb +298 -0
  204. data/lib/chef/role.rb +301 -0
  205. data/lib/chef/run_list.rb +164 -0
  206. data/lib/chef/runner.rb +130 -0
  207. data/lib/chef/search/query.rb +71 -0
  208. data/lib/chef/shef.rb +220 -0
  209. data/lib/chef/shef/ext.rb +297 -0
  210. data/lib/chef/shef/shef_session.rb +175 -0
  211. data/lib/chef/streaming_cookbook_uploader.rb +185 -0
  212. data/lib/chef/tasks/chef_repo.rake +245 -0
  213. data/lib/chef/util/file_edit.rb +125 -0
  214. data/lib/chef/util/fileedit.rb +121 -0
  215. data/lib/chef/webui_user.rb +231 -0
  216. metadata +398 -0
@@ -0,0 +1,72 @@
1
+ #
2
+ # Author:: Joe Williams (<joe@joetify.com>)
3
+ # Copyright:: Copyright (c) 2009 Joe Williams
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/log'
20
+ require 'chef/mixin/command'
21
+ require 'chef/provider'
22
+
23
+ class Chef
24
+ class Provider
25
+ class ErlCall < Chef::Provider
26
+ include Chef::Mixin::Command
27
+
28
+ def initialize(node, new_resource)
29
+ super(node, new_resource)
30
+ end
31
+
32
+ def load_current_resource
33
+ true
34
+ end
35
+
36
+ def action_run
37
+ case @new_resource.name_type
38
+ when "sname"
39
+ node = "-sname #{@new_resource.node_name}"
40
+ when "name"
41
+ node = "-name #{@new_resource.node_name}"
42
+ end
43
+
44
+ if @new_resource.cookie
45
+ cookie = "-c #{@new_resource.cookie}"
46
+ else
47
+ cookie = ""
48
+ end
49
+
50
+ if @new_resource.distributed
51
+ distributed = "-s"
52
+ else
53
+ distributed = ""
54
+ end
55
+
56
+ command = "erl_call -e #{distributed} #{node} #{cookie}"
57
+
58
+ status = popen4(command, :waitlast => true) do |pid, stdin, stdout, stderr|
59
+ Chef::Log.debug("Running erl_call[#{@new_resource.name}]")
60
+ Chef::Log.debug("erl_call[#{@new_resource.name}] command: #{command}")
61
+ Chef::Log.debug("erl_call[#{@new_resource.name}] code: #{@new_resource.code}")
62
+ @new_resource.code.each { |line| stdin.puts "#{line.chomp!}" }
63
+ stdin.close
64
+ Chef::Log.info("Ran erl_call[#{@new_resource.name}] successfully")
65
+ Chef::Log.debug("erl_call[#{@new_resource.name}] output: ")
66
+ stdout.each { |line| Chef::Log.debug("#{line}")}
67
+ end
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,58 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/mixin/command'
20
+ require 'chef/log'
21
+ require 'chef/provider'
22
+
23
+ class Chef
24
+ class Provider
25
+ class Execute < Chef::Provider
26
+
27
+ include Chef::Mixin::Command
28
+
29
+ def load_current_resource
30
+ true
31
+ end
32
+
33
+ def action_run
34
+ command_args = {
35
+ :command => @new_resource.command,
36
+ :command_string => @new_resource.to_s,
37
+ }
38
+ command_args[:creates] = @new_resource.creates if @new_resource.creates
39
+ command_args[:only_if] = @new_resource.only_if if @new_resource.only_if
40
+ command_args[:not_if] = @new_resource.not_if if @new_resource.not_if
41
+ command_args[:timeout] = @new_resource.timeout if @new_resource.timeout
42
+ command_args[:returns] = @new_resource.returns if @new_resource.returns
43
+ command_args[:environment] = @new_resource.environment if @new_resource.environment
44
+ command_args[:user] = @new_resource.user if @new_resource.user
45
+ command_args[:group] = @new_resource.group if @new_resource.group
46
+ command_args[:cwd] = @new_resource.cwd if @new_resource.cwd
47
+ command_args[:umask] = @new_resource.umask if @new_resource.umask
48
+
49
+ status = run_command(command_args)
50
+ if status
51
+ @new_resource.updated = true
52
+ Chef::Log.info("Ran #{@new_resource} successfully")
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,195 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/config'
20
+ require 'chef/log'
21
+ require 'chef/resource/file'
22
+ require 'chef/mixin/checksum'
23
+ require 'chef/mixin/generate_url'
24
+ require 'chef/provider'
25
+ require 'etc'
26
+ require 'fileutils'
27
+
28
+ class Chef
29
+ class Provider
30
+ class File < Chef::Provider
31
+ include Chef::Mixin::Checksum
32
+ include Chef::Mixin::GenerateURL
33
+
34
+ def negative_complement(big)
35
+ if big > 1073741823 # Fixnum max
36
+ big -= (2**32) # diminished radix wrap to negative
37
+ end
38
+ big
39
+ end
40
+
41
+ def octal_mode(mode)
42
+ ((mode.respond_to?(:oct) ? mode.oct : mode.to_i) & 007777)
43
+ end
44
+
45
+ private :negative_complement, :octal_mode
46
+
47
+ def load_current_resource
48
+ @current_resource = Chef::Resource::File.new(@new_resource.name)
49
+ @current_resource.path(@new_resource.path)
50
+ if ::File.exist?(@current_resource.path) && ::File.readable?(@current_resource.path)
51
+ cstats = ::File.stat(@current_resource.path)
52
+ @current_resource.owner(cstats.uid)
53
+ @current_resource.group(cstats.gid)
54
+ @current_resource.mode(octal_mode(cstats.mode))
55
+ @current_resource.checksum(checksum(@current_resource.path))
56
+ end
57
+ @current_resource
58
+ end
59
+
60
+ # Compare the ownership of a file. Returns true if they are the same, false if they are not.
61
+ def compare_owner
62
+ return false if @new_resource.owner.nil?
63
+
64
+ @set_user_id = case @new_resource.owner
65
+ when /^\d+$/, Integer
66
+ @new_resource.owner.to_i
67
+ else
68
+ # This raises an ArgumentError if you can't find the user
69
+ Etc.getpwnam(@new_resource.owner).uid
70
+ end
71
+
72
+ @set_user_id == @current_resource.owner
73
+ end
74
+
75
+ # Set the ownership on the file, assuming it is not set correctly already.
76
+ def set_owner
77
+ unless compare_owner
78
+ Chef::Log.info("Setting owner to #{@set_user_id} for #{@new_resource}")
79
+ @set_user_id = negative_complement(@set_user_id)
80
+ ::File.chown(@set_user_id, nil, @new_resource.path)
81
+ @new_resource.updated = true
82
+ end
83
+ end
84
+
85
+ # Compares the group of a file. Returns true if they are the same, false if they are not.
86
+ def compare_group
87
+ return false if @new_resource.group.nil?
88
+
89
+ @set_group_id = case @new_resource.group
90
+ when /^\d+$/, Integer
91
+ @new_resource.group.to_i
92
+ else
93
+ Etc.getgrnam(@new_resource.group).gid
94
+ end
95
+
96
+ @set_group_id == @current_resource.group
97
+ end
98
+
99
+ def set_group
100
+ unless compare_group
101
+ Chef::Log.info("Setting group to #{@set_group_id} for #{@new_resource}")
102
+ @set_group_id = negative_complement(@set_group_id)
103
+ ::File.chown(nil, @set_group_id, @new_resource.path)
104
+ @new_resource.updated = true
105
+ end
106
+ end
107
+
108
+ def compare_mode
109
+ case @new_resource.mode
110
+ when /^\d+$/, Integer
111
+ octal_mode(@new_resource.mode) == octal_mode(@current_resource.mode)
112
+ else
113
+ false
114
+ end
115
+ end
116
+
117
+ def set_mode
118
+ unless compare_mode && @new_resource.mode != nil
119
+ Chef::Log.info("Setting mode to #{sprintf("%o" % octal_mode(@new_resource.mode))} for #{@new_resource}")
120
+ # CHEF-174, bad mojo around treating integers as octal. If a string is passed, we try to do the "right" thing
121
+ ::File.chmod(octal_mode(@new_resource.mode), @new_resource.path)
122
+ @new_resource.updated = true
123
+ end
124
+ end
125
+
126
+ def action_create
127
+ unless ::File.exists?(@new_resource.path)
128
+ Chef::Log.info("Creating #{@new_resource} at #{@new_resource.path}")
129
+ ::File.open(@new_resource.path, "w+") { |f| }
130
+ @new_resource.updated = true
131
+ end
132
+ set_owner unless @new_resource.owner.nil?
133
+ set_group unless @new_resource.group.nil?
134
+ set_mode unless @new_resource.mode.nil?
135
+ end
136
+
137
+ def action_create_if_missing
138
+ action_create
139
+ end
140
+
141
+ def action_delete
142
+ if ::File.exists?(@new_resource.path)
143
+ if ::File.writable?(@new_resource.path)
144
+ backup unless ::File.symlink?(@new_resource.path)
145
+ Chef::Log.info("Deleting #{@new_resource} at #{@new_resource.path}")
146
+ ::File.delete(@new_resource.path)
147
+ @new_resource.updated = true
148
+ else
149
+ raise "Cannot delete #{@new_resource} at #{@new_resource_path}!"
150
+ end
151
+ end
152
+ end
153
+
154
+ def action_touch
155
+ action_create
156
+ time = Time.now
157
+ Chef::Log.info("Updating #{@new_resource} with new atime/mtime of #{time}")
158
+ ::File.utime(time, time, @new_resource.path)
159
+ @new_resource.updated = true
160
+ end
161
+
162
+ def backup(file=nil)
163
+ file ||= @new_resource.path
164
+ if @new_resource.backup != false && @new_resource.backup > 0 && ::File.exist?(file)
165
+ time = Time.now
166
+ savetime = time.strftime("%Y%m%d%H%M%S")
167
+ backup_filename = "#{@new_resource.path}.chef-#{savetime}"
168
+ prefix = Chef::Config[:file_backup_path] || ""
169
+ if Chef::Config[:file_backup_path]
170
+ FileUtils.mkdir_p(::File.dirname(Chef::Config[:file_backup_path] + backup_filename))
171
+ end
172
+ Chef::Log.info("Backing up #{@new_resource} to #{backup_filename}")
173
+ FileUtils.cp(file, prefix + backup_filename, :preserve => true)
174
+
175
+ # Clean up after the number of backups
176
+ slice_number = @new_resource.backup
177
+ backup_files = Dir[prefix + "#{@new_resource.path}.chef-*"].sort { |a,b| b <=> a }
178
+ if backup_files.length >= @new_resource.backup
179
+ remainder = backup_files.slice(slice_number..-1)
180
+ remainder.each do |backup_to_delete|
181
+ Chef::Log.info("Removing backup of #{@new_resource} at #{backup_to_delete}")
182
+ FileUtils.rm(backup_to_delete)
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ def generate_url(url, type, args=nil)
189
+ cookbook_name = (@new_resource.respond_to?(:cookbook) && @new_resource.cookbook) ? @new_resource.cookbook : @new_resource.cookbook_name
190
+ generate_cookbook_url(url, cookbook_name, type, @node, args)
191
+ end
192
+
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,203 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@kallistec.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+
20
+ require 'chef/log'
21
+ require 'chef/provider'
22
+ require 'chef/mixin/command'
23
+ require 'fileutils'
24
+
25
+ class Chef
26
+ class Provider
27
+ class Git < Chef::Provider
28
+
29
+ include Chef::Mixin::Command
30
+
31
+ def load_current_resource
32
+ @current_resource = Chef::Resource::Git.new(@new_resource.name)
33
+ if current_revision = find_current_revision
34
+ @current_resource.revision current_revision
35
+ end
36
+ end
37
+
38
+ def action_checkout
39
+ if !::File.exist?(@new_resource.destination) || Dir.entries(@new_resource.destination) == ['.','..']
40
+ clone
41
+ checkout
42
+ enable_submodules
43
+ @new_resource.updated = true
44
+ else
45
+ Chef::Log.info "Taking no action, checkout destination #{@new_resource.destination} already exists or is a non-empty directory"
46
+ end
47
+ end
48
+
49
+ def action_export
50
+ action_checkout
51
+ FileUtils.rm_rf(::File.join(@new_resource.destination,".git"))
52
+ @new_resource.updated = true
53
+ end
54
+
55
+ def action_sync
56
+ if !::File.exist?(@new_resource.destination) || Dir.entries(@new_resource.destination) == ['.','..']
57
+ action_checkout
58
+ else
59
+ sync
60
+ enable_submodules
61
+ end
62
+
63
+ @new_resource.updated = true
64
+ end
65
+
66
+ def find_current_revision
67
+ if ::File.exist?(::File.join(cwd, ".git"))
68
+ status, result, error_message = output_of_command("git rev-parse HEAD", run_options(:cwd=>cwd))
69
+
70
+ # 128 is returned when we're not in a git repo. this is fine
71
+ unless [0,128].include?(status.exitstatus)
72
+ handle_command_failures(status, "STDOUT: #{result}\nSTDERR: #{error_message}")
73
+ end
74
+ end
75
+ sha_hash?(result) ? result : nil
76
+ end
77
+
78
+ def clone
79
+ remote = @new_resource.remote
80
+
81
+ args = []
82
+ args << "-o #{remote}" unless remote == 'origin'
83
+ args << "--depth #{@new_resource.depth}" if @new_resource.depth
84
+
85
+ Chef::Log.info "Cloning repo #{@new_resource.repository} to #{@new_resource.destination}"
86
+
87
+ clone_cmd = "#{git} clone #{args.join(' ')} #{@new_resource.repository} #{@new_resource.destination}"
88
+ run_command(run_options(:command => clone_cmd))
89
+ end
90
+
91
+ def checkout
92
+ sha_ref = revision_sha
93
+ Chef::Log.info "Checking out branch: #{@new_resource.revision} reference: #{sha_ref}"
94
+ # checkout into a local branch rather than a detached HEAD
95
+ run_command(run_options(:command => "#{git} checkout -b deploy #{sha_ref}", :cwd => @new_resource.destination))
96
+ end
97
+
98
+ def enable_submodules
99
+ if @new_resource.enable_submodules
100
+ Chef::Log.info "Enabling git submodules"
101
+ command = "#{git} submodule init && #{git} submodule update"
102
+ run_command(run_options(:command => command, :cwd => @new_resource.destination))
103
+ end
104
+ end
105
+
106
+ def sync
107
+ revision = revision_sha
108
+ sync_command = []
109
+
110
+ # Use git-config to setup a remote tracking branches. Could use
111
+ # git-remote but it complains when a remote of the same name already
112
+ # exists, git-config will just silenty overwrite the setting every
113
+ # time. This could cause wierd-ness in the remote cache if the url
114
+ # changes between calls, but as long as the repositories are all
115
+ # based from each other it should still work fine.
116
+ if @new_resource.remote != 'origin'
117
+ Chef::Log.info "Configuring remote tracking branches for repository #{@new_resource.repository} "+
118
+ "at remote #{@new_resource.remote}"
119
+ sync_command << "#{git} config remote.#{@new_resource.remote}.url #{@new_resource.repository}"
120
+ sync_command << "#{git} config remote.#{@new_resource.remote}.fetch +refs/heads/*:refs/remotes/#{@new_resource.remote}/*"
121
+ end
122
+
123
+ # since we're in a local branch already, just reset to specified revision rather than merge
124
+ sync_command << "#{git} fetch #{@new_resource.remote} --tags && #{git} reset --hard #{revision}"
125
+ Chef::Log.info "Fetching updates from #{new_resource.remote} and resetting to revison #{revision}"
126
+ run_command(run_options(:command => sync_command.join(" && "), :cwd => @new_resource.destination))
127
+ end
128
+
129
+ def revision_sha
130
+ @revision_sha ||= begin
131
+ assert_revision_not_remote
132
+
133
+ if sha_hash?(@new_resource.revision)
134
+ @revision_sha = @new_resource.revision
135
+ else
136
+ resolved_reference = remote_resolve_reference
137
+ @revision_sha = extract_revision(resolved_reference)
138
+ end
139
+ end
140
+ end
141
+
142
+ alias :revision_slug :revision_sha
143
+
144
+ def remote_resolve_reference
145
+ command = scm('ls-remote', @new_resource.repository, @new_resource.revision)
146
+ Chef::Log.debug("Executing #{command}")
147
+ begin
148
+ status, result, error_message = output_of_command(command, run_options)
149
+ handle_command_failures(status, "STDOUT: #{result}\nSTDERR: #{error_message}")
150
+ rescue RuntimeError => e
151
+ raise RuntimeError, e.message + "\n" + "Could not access the remote Git repository. "+
152
+ "If this is a private repository, please verify that the deploy key for your application " +
153
+ "has been added to your remote Git account."
154
+ end
155
+ result
156
+ end
157
+
158
+ private
159
+
160
+ def run_options(run_opts={})
161
+ run_opts[:user] = @new_resource.user if @new_resource.user
162
+ run_opts[:group] = @new_resource.group if @new_resource.group
163
+ run_opts[:environment] = {"GIT_SSH" => @new_resource.ssh_wrapper} if @new_resource.ssh_wrapper
164
+ run_opts
165
+ end
166
+
167
+ def cwd
168
+ @new_resource.destination
169
+ end
170
+
171
+ def scm(*args)
172
+ [git, *args].compact.join(" ")
173
+ end
174
+
175
+ def git
176
+ 'git'
177
+ end
178
+
179
+ def sha_hash?(string)
180
+ string =~ /^[0-9a-f]{40}$/
181
+ end
182
+
183
+ def assert_revision_not_remote
184
+ if @new_resource.revision =~ /^origin\//
185
+ reference = @new_resource.revision
186
+ error_text = "Deploying remote branches is not supported. " +
187
+ "Specify the remote branch as a local branch for " +
188
+ "the git repository you're deploying from " +
189
+ "(ie: '#{reference.gsub('origin/', '')}' rather than '#{reference}')."
190
+ raise RuntimeError, error_text
191
+ end
192
+ end
193
+
194
+ def extract_revision(resolved_reference)
195
+ unless resolved_reference =~ /^([0-9a-f]{40})\s+(\S+)/
196
+ raise "Unable to resolve reference for '#{resolved_reference}' on repository '#{@new_resource.repository}'."
197
+ end
198
+ $1
199
+ end
200
+
201
+ end
202
+ end
203
+ end