PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/chef/cookbooks/provisioner/recipes/base.rb

https://github.com/crowbar/barclamp-provisioner
Ruby | 387 lines | 300 code | 43 blank | 44 comment | 34 complexity | 439c22d07b242ab44da4b53bde69547c MD5 | raw file
  1. # Copyright 2011, Dell
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. #
  15. return if node[:platform] == "windows"
  16. ###
  17. # If anything has to be applied to a Windows node, it has to be done
  18. # before the return above, anything from this point forward being applied
  19. # to linux nodes only.
  20. ###
  21. package "ipmitool" do
  22. package_name "OpenIPMI-tools" if node[:platform] =~ /^(redhat|centos)$/
  23. action :install
  24. end
  25. directory "/root/.ssh" do
  26. owner "root"
  27. group "root"
  28. mode "0700"
  29. action :create
  30. end
  31. # We don't want to use bluepill on SUSE and Windows
  32. if node["platform"] != "suse"
  33. # Make sure we have Bluepill
  34. case node["state"]
  35. when "ready","readying"
  36. include_recipe "bluepill"
  37. end
  38. end
  39. node.set["crowbar"]["ssh"] ||= {}
  40. # Start with a blank slate, to ensure that any keys removed from a
  41. # previously applied proposal will be removed. It also means that any
  42. # keys manually added to authorized_keys will be automatically removed
  43. # by Chef.
  44. node.set["crowbar"]["ssh"]["access_keys"] = {}
  45. # Build my key
  46. if ::File.exists?("/root/.ssh/id_rsa.pub") == false
  47. %x{ssh-keygen -t rsa -f /root/.ssh/id_rsa -N ""}
  48. end
  49. str = %x{cat /root/.ssh/id_rsa.pub}.chomp
  50. node.set["crowbar"]["ssh"]["root_pub_key"] = str
  51. node.set["crowbar"]["ssh"]["access_keys"][node.name] = str
  52. # Add additional keys
  53. node["provisioner"]["access_keys"].strip.split("\n").each do |key|
  54. key.strip!
  55. if !key.empty?
  56. nodename = key.split(" ")[2]
  57. node.set["crowbar"]["ssh"]["access_keys"][nodename] = key
  58. end
  59. end
  60. # Find provisioner servers and include them.
  61. provisioner_server_node = nil
  62. search(:node, "roles:provisioner-server AND provisioner_config_environment:#{node[:provisioner][:config][:environment]}") do |n|
  63. provisioner_server_node = n if provisioner_server_node.nil?
  64. pkey = n["crowbar"]["ssh"]["root_pub_key"] rescue nil
  65. if !pkey.nil? and pkey != node["crowbar"]["ssh"]["access_keys"][n.name]
  66. node.set["crowbar"]["ssh"]["access_keys"][n.name] = pkey
  67. end
  68. end
  69. # Fix bug we had in stoney and earlier where we never saved the target_platform
  70. # of the node when the node was installed with the default target platform.
  71. # This only works because the default target platform didn't change between
  72. # stoney and tex.
  73. if node[:target_platform].nil? or node[:target_platform].empty?
  74. node.set[:target_platform] = provisioner_server_node[:provisioner][:default_os]
  75. end
  76. node.save
  77. template "/root/.ssh/authorized_keys" do
  78. owner "root"
  79. group "root"
  80. mode "0644"
  81. action :create
  82. source "authorized_keys.erb"
  83. variables(:keys => node["crowbar"]["ssh"]["access_keys"])
  84. end
  85. template "/etc/sudo.conf" do
  86. source "sudo.conf.erb"
  87. owner "root"
  88. group "root"
  89. mode "0644"
  90. end
  91. # Also put authorized_keys in tftpboot path on the admin node so that discovered
  92. # nodes can use the same.
  93. if node.roles.include? "crowbar"
  94. case node[:platform]
  95. when "suse"
  96. tftpboot_path = "/srv/tftpboot"
  97. else
  98. tftpboot_path = "/tftpboot"
  99. end
  100. template "#{tftpboot_path}/authorized_keys" do
  101. owner "root"
  102. group "root"
  103. mode "0644"
  104. action :create
  105. source "authorized_keys.erb"
  106. variables(:keys => node["crowbar"]["ssh"]["access_keys"])
  107. end
  108. end
  109. bash "Disable Strict Host Key checking" do
  110. code "echo ' StrictHostKeyChecking no' >>/etc/ssh/ssh_config"
  111. not_if "grep -q 'StrictHostKeyChecking no' /etc/ssh/ssh_config"
  112. end
  113. bash "Set EDITOR=vi environment variable" do
  114. code "echo \"EDITOR=vi\" > /etc/profile.d/editor.sh"
  115. not_if "export | grep -q EDITOR="
  116. end
  117. sysctl_core_dump_file = "/etc/sysctl.d/core-dump.conf"
  118. if node[:provisioner][:coredump]
  119. directory "create /etc/sysctl.d for core-dump" do
  120. path "/etc/sysctl.d"
  121. mode "755"
  122. end
  123. cookbook_file sysctl_core_dump_file do
  124. owner "root"
  125. group "root"
  126. mode "0644"
  127. action :create
  128. source "core-dump.conf"
  129. end
  130. bash "reload core-dump-sysctl" do
  131. code "/sbin/sysctl -e -q -p #{sysctl_core_dump_file}"
  132. action :nothing
  133. subscribes :run, resources(:cookbook_file=> sysctl_core_dump_file), :delayed
  134. end
  135. bash "Enable core dumps" do
  136. code "ulimit -c unlimited"
  137. end
  138. # Permanent core dumping (needs reboot)
  139. bash "Enable permanent core dumps (/etc/security/limits)" do
  140. code "echo '* soft core unlimited' >> /etc/security/limits.conf"
  141. not_if "grep -q 'soft core unlimited' /etc/security/limits.conf"
  142. end
  143. if node[:platform] == "suse"
  144. if node[:platform_version].to_f < 12.0
  145. package "ulimit"
  146. # Permanent core dumping (no reboot needed)
  147. bash "Enable permanent core dumps (/etc/sysconfig/ulimit)" do
  148. code 'sed -i s/SOFTCORELIMIT.*/SOFTCORELIMIT="unlimited"/ /etc/sysconfig/ulimit'
  149. not_if "grep -q '^SOFTCORELIMIT=\"unlimited\"' /etc/sysconfig/ulimit"
  150. end
  151. else
  152. # Permanent core dumping (no reboot needed)
  153. bash "Enable permanent core dumps (/etc/systemd/system.conf)" do
  154. code 'sed -i s/^#*DefaultLimitCORE=.*/DefaultLimitCORE=infinity/ /etc/systemd/system.conf'
  155. not_if "grep -q '^DefaultLimitCORE=infinity' /etc/systemd/system.conf"
  156. end
  157. end
  158. end
  159. else
  160. file sysctl_core_dump_file do
  161. action :delete
  162. end
  163. bash "Disable permanent core dumps (/etc/security/limits)" do
  164. code 'sed -is "/\* soft core unlimited/d" /etc/security/limits.conf'
  165. only_if "grep -q '* soft core unlimited' /etc/security/limits.conf"
  166. end
  167. if node[:platform] == "suse"
  168. if node[:platform_version].to_f < 12.0
  169. package "ulimit"
  170. bash "Disable permanent core dumps (/etc/sysconfig/ulimit)" do
  171. code 'sed -i s/SOFTCORELIMIT.*/SOFTCORELIMIT="1"/ /etc/sysconfig/ulimit'
  172. not_if "grep -q '^SOFTCORELIMIT=\"1\"' /etc/sysconfig/ulimit"
  173. end
  174. else
  175. bash "Disable permanent core dumps (/etc/sysconfig/ulimit)" do
  176. code 'sed -i s/^DefaultLimitCORE=.*/#DefaultLimitCORE=/ /etc/systemd/system.conf'
  177. not_if "grep -q '^#DefaultLimitCORE=' /etc/systemd/system.conf"
  178. end
  179. end
  180. end
  181. end
  182. config_file = "/etc/default/chef-client"
  183. config_file = "/etc/sysconfig/chef-client" if node[:platform] =~ /^(redhat|centos)$/
  184. cookbook_file config_file do
  185. owner "root"
  186. group "root"
  187. mode "0644"
  188. action :create
  189. source "chef-client"
  190. end
  191. # On SUSE: install crowbar_join properly, with init script
  192. if node["platform"] == "suse" && !node.roles.include?("provisioner-server")
  193. admin_ip = Chef::Recipe::Barclamp::Inventory.get_network_by_type(provisioner_server_node, "admin").address
  194. web_port = provisioner_server_node[:provisioner][:web_port]
  195. ntp_servers = search(:node, "roles:ntp-server")
  196. ntp_servers_ips = ntp_servers.map { |n| Chef::Recipe::Barclamp::Inventory.get_network_by_type(n, "admin").address }
  197. template "/usr/sbin/crowbar_join" do
  198. mode 0755
  199. owner "root"
  200. group "root"
  201. source "crowbar_join.suse.sh.erb"
  202. variables(:admin_ip => admin_ip,
  203. :web_port => web_port,
  204. :ntp_servers_ips => ntp_servers_ips,
  205. :target_platform_version => node["platform_version"] )
  206. end
  207. if node["platform_version"].to_f < 12.0
  208. cookbook_file "/etc/init.d/crowbar_join" do
  209. owner "root"
  210. group "root"
  211. mode "0755"
  212. action :create
  213. source "crowbar_join.init.suse"
  214. end
  215. link "/usr/sbin/rccrowbar_join" do
  216. action :create
  217. to "/etc/init.d/crowbar_join"
  218. end
  219. # Make sure that any dependency change is taken into account
  220. bash "insserv crowbar_join service" do
  221. code "insserv crowbar_join"
  222. action :nothing
  223. subscribes :run, resources(:cookbook_file=> "/etc/init.d/crowbar_join"), :delayed
  224. end
  225. else
  226. # Use a systemd .service file on SLE12
  227. cookbook_file "/etc/systemd/system/crowbar_notify_shutdown.service" do
  228. owner "root"
  229. group "root"
  230. mode "0644"
  231. action :create
  232. source "crowbar_notify_shutdown.service"
  233. end
  234. cookbook_file "/etc/systemd/system/crowbar_join.service" do
  235. owner "root"
  236. group "root"
  237. mode "0644"
  238. action :create
  239. source "crowbar_join.service"
  240. end
  241. # Make sure that any dependency change is taken into account
  242. bash "reload systemd after crowbar_join update" do
  243. code "systemctl daemon-reload"
  244. action :nothing
  245. subscribes :run, resources(:cookbook_file=> "/etc/systemd/system/crowbar_notify_shutdown.service"), :immediately
  246. subscribes :run, resources(:cookbook_file=> "/etc/systemd/system/crowbar_join.service"), :immediately
  247. end
  248. link "/usr/sbin/rccrowbar_join" do
  249. action :create
  250. to "service"
  251. end
  252. service "crowbar_notify_shutdown" do
  253. action [:enable, :start]
  254. end
  255. end
  256. service "crowbar_join" do
  257. action :enable
  258. end
  259. cookbook_file "/etc/logrotate.d/crowbar_join" do
  260. owner "root"
  261. group "root"
  262. mode "0644"
  263. source "crowbar_join.logrotate.suse"
  264. action :create
  265. end
  266. # remove old crowbar_join.sh file
  267. file "/etc/init.d/crowbar_join.sh" do
  268. action :delete
  269. end
  270. if node["platform"] == "suse"
  271. ## make sure the repos are properly setup
  272. repos = Provisioner::Repositories.get_repos(provisioner_server_node, node["platform"], node["platform_version"])
  273. for name, attrs in repos
  274. url = %x{zypper --non-interactive repos #{name} 2> /dev/null | grep "^URI " | cut -d : -f 2-}
  275. url.strip!
  276. if url != attrs[:url]
  277. unless url.empty?
  278. Chef::Log.info("Removing #{name} zypper repository pointing to wrong URI...")
  279. %x{zypper --non-interactive removerepo #{name}}
  280. end
  281. Chef::Log.info("Adding #{name} zypper repository...")
  282. %x{zypper --non-interactive addrepo --refresh #{attrs[:url]} #{name}}
  283. end
  284. end
  285. # install additional packages
  286. os = "#{node[:platform]}-#{node[:platform_version]}"
  287. if node[:provisioner][:packages][os]
  288. node[:provisioner][:packages][os].each { |p| package p }
  289. end
  290. end
  291. end
  292. aliaz = begin
  293. display_alias = node["crowbar"]["display"]["alias"]
  294. if display_alias && !display_alias.empty?
  295. display_alias
  296. else
  297. node["hostname"]
  298. end
  299. rescue
  300. node["hostname"]
  301. end
  302. %w(/etc/profile.d/zzz-prompt.sh /etc/profile.d/zzz-prompt.csh).each do |cfg|
  303. template cfg do
  304. source "zzz-prompt.sh.erb"
  305. owner "root"
  306. group "root"
  307. mode "0644"
  308. variables(
  309. :prompt_from_template => proc { |user, cwd|
  310. node["provisioner"]["shell_prompt"].to_s \
  311. .gsub("USER", user) \
  312. .gsub("CWD", cwd) \
  313. .gsub("SUFFIX", "${prompt_suffix}") \
  314. .gsub("ALIAS", aliaz) \
  315. .gsub("HOST", node["hostname"]) \
  316. .gsub("FQDN", node["fqdn"])
  317. },
  318. :zsh_prompt_from_template => proc {
  319. node["provisioner"]["shell_prompt"].to_s \
  320. .gsub("USER", "%{\\e[0;31m%}%n%{\\e[0m%}") \
  321. .gsub("CWD", "%{\\e[0;35m%}%~%{\\e[0m%}") \
  322. .gsub("SUFFIX", "%#") \
  323. .gsub("ALIAS", "%{\\e[0;35m%}#{aliaz}%{\\e[0m%}") \
  324. .gsub("HOST", "%{\\e[0;35m%}#{node["hostname"]}%{\\e[0m%}") \
  325. .gsub("FQDN", "%{\\e[0;35m%}#{node["fqdn"]}%{\\e[0m%}")
  326. },
  327. :bash_prompt_from_template => proc {
  328. node["provisioner"]["shell_prompt"].to_s \
  329. .gsub("USER", "\\[\\e[01;31m\\]\\u\\[\\e[0m\\]") \
  330. .gsub("CWD", "\\[\\e[01;31m\\]\\w\\[\\e[0m\\]") \
  331. .gsub("SUFFIX", "${prompt_suffix}") \
  332. .gsub("ALIAS", "\\[\\e[01;35m\\]#{aliaz}\\[\\e[0m\\]") \
  333. .gsub("HOST", "\\[\\e[01;35m\\]#{node["hostname"]}\\[\\e[0m\\]") \
  334. .gsub("FQDN", "\\[\\e[01;35m\\]#{node["fqdn"]}\\[\\e[0m\\]")
  335. }
  336. )
  337. end
  338. end
  339. template "/etc/sh.shrc.local" do
  340. source "shrc.local.erb"
  341. owner "root"
  342. group "root"
  343. mode "0644"
  344. end