/src/clj/backtype/storm/crate/zookeeper.clj

http://github.com/nathanmarz/storm-deploy · Clojure · 231 lines · 214 code · 17 blank · 0 comment · 3 complexity · e948250362836e73ca252ea63a59a874 MD5 · raw file

  1. (ns backtype.storm.crate.zookeeper
  2. (:require
  3. [pallet.action.directory :as directory]
  4. [pallet.action.file :as file]
  5. [pallet.action.remote-directory :as remote-directory]
  6. [pallet.action.remote-file :as remote-file]
  7. [pallet.action.service :as service]
  8. [pallet.action.user :as user]
  9. [pallet.argument :as argument]
  10. [pallet.compute :as compute]
  11. [pallet.parameter :as parameter]
  12. [pallet.session :as session]
  13. [pallet.stevedore :as stevedore]
  14. [clojure.string :as string]
  15. [pallet.resource.package :as package]
  16. [pallet.action.exec-script :as exec-script]
  17. [pallet.crate.crontab :as crontab]
  18. )
  19. (:use
  20. pallet.thread-expr))
  21. (def install-path "/usr/local/zookeeper")
  22. (def log-path "/var/log/zookeeper")
  23. (def tx-log-path "/mnt/zookeeper")
  24. (def config-path "/etc/zookeeper")
  25. (def data-path "/var/zookeeper")
  26. (def zookeeper-home install-path)
  27. (def zookeeper-user "zookeeper")
  28. (def zookeeper-group "zookeeper")
  29. (def default-config
  30. {:dataDir data-path
  31. :tickTime 2000
  32. :clientPort 2181
  33. :initLimit 10
  34. :syncLimit 5
  35. :dataLogDir tx-log-path})
  36. (defn url "Download url"
  37. [version]
  38. (format
  39. "http://www.apache.org/dist/zookeeper/zookeeper-%s/zookeeper-%s.tar.gz"
  40. version version))
  41. (defn install
  42. "Install Zookeeper"
  43. [session & {:keys [user group version home]
  44. :or {user zookeeper-user
  45. group zookeeper-group
  46. version "3.3.6"}
  47. :as options}]
  48. (let [url (url version)
  49. home (or home (format "%s-%s" install-path version))]
  50. (->
  51. session
  52. (package/package "daemontools")
  53. (parameter/assoc-for
  54. [:zookeeper :home] home
  55. [:zookeeper :owner] user
  56. [:zookeeper :group] group)
  57. (user/group group :system true)
  58. (user/user user :system true :group group)
  59. (remote-directory/remote-directory
  60. home
  61. :url url :md5-url (str url ".md5")
  62. :unpack :tar :tar-options "xz"
  63. :owner user :group group)
  64. (directory/directory log-path :owner user :group group :mode "0755")
  65. (directory/directory tx-log-path :owner user :group group :mode "0755")
  66. (directory/directory config-path :owner user :group group :mode "0755")
  67. (directory/directory data-path :owner user :group group :mode "0755")
  68. (directory/directory (format "/home/%s" user) :owner user :group group :mode "0755")
  69. (directory/directory (format "%s/supervise" home) :owner user :group group :mode "0755")
  70. (remote-file/remote-file
  71. (format "%s/purge" home)
  72. :content
  73. (format
  74. "#!/bin/bash
  75. cd %s && export ZOOBINDIR=\"bin\" && . bin/zkEnv.sh && echo $CLASSPATH && java -cp $CLASSPATH org.apache.zookeeper.server.PurgeTxnLog %s %s -n 3
  76. "
  77. home
  78. tx-log-path
  79. data-path
  80. )
  81. :overwrite-changes true
  82. :literal true
  83. :mode 755)
  84. (remote-file/remote-file
  85. (format "%s/run" home)
  86. :content
  87. "#!/bin/bash
  88. export ZOOBINDIR=\".\"
  89. if [ \"x$JMXLOCALONLY\" = \"x\" ]
  90. then
  91. JMXLOCALONLY=false
  92. fi
  93. if [ \"x$JMXDISABLE\" = \"x\" ]
  94. then
  95. echo \"JMX enabled by default\"
  96. # for some reason these two options are necessary on jdk6 on Ubuntu
  97. # accord to the docs they are not necessary, but otw jconsole cannot
  98. # do a local attach
  99. ZOOMAIN=\"-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY org.apache.zookeeper.server.quorum.QuorumPeerMain\"
  100. else
  101. echo \"JMX disabled by user request\"
  102. ZOOMAIN=\"org.apache.zookeeper.server.quorum.QuorumPeerMain\"
  103. fi
  104. if [ \"x$2\" != \"x\" ]
  105. then
  106. ZOOCFG=\"$ZOOCFGDIR/$2\"
  107. fi
  108. cd bin && . ./zkEnv.sh && java \"-Dzookeeper.log.dir=${ZOO_LOG_DIR}\" \"-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}\" -cp \"$CLASSPATH\" $JVMFLAGS $ZOOMAIN \"$ZOOCFG\"
  109. "
  110. :overwrite-changes true
  111. :literal true
  112. :mode 755)
  113. (remote-file/remote-file
  114. (format "%s/log4j.properties" config-path)
  115. :remote-file (format "%s/conf/log4j.properties" home)
  116. :owner user :group group :mode "0644")
  117. (file/sed
  118. (format "%s/bin/zkServer.sh" home)
  119. {"# chkconfig:.*" ""
  120. "# description:.*" ""
  121. "# by default we allow local JMX connections"
  122. "# by default we allow local JMX connections\\n# chkconfig: 2345 20 80\\n# description: zookeeper"})
  123. (file/sed
  124. (format "%s/log4j.properties" config-path)
  125. {"log4j.rootLogger=INFO, CONSOLE"
  126. "log4j.rootLogger=INFO, ROLLINGFILE"
  127. "log4j.appender.ROLLINGFILE.File=zookeeper.log"
  128. (format "log4j.appender.ROLLINGFILE.File=%s/zookeeper.log" log-path)}
  129. :seperator "|")
  130. )))
  131. (defn init [session]
  132. (-> session
  133. (exec-script/exec-script
  134. (cd ~(parameter/get-for session [:zookeeper :home]))
  135. "sudo -u " ~(parameter/get-for session [:zookeeper :owner]) " nohup supervise . &")
  136. (crontab/crontab "root"
  137. :content (format "@daily sh %s/purge" (parameter/get-for session [:zookeeper :home])))
  138. ))
  139. (defn config-files
  140. "Create a zookeeper configuration file. We sort by name to preserve sequence
  141. across invocations."
  142. [session]
  143. (let [target-name (session/target-name session)
  144. target-ip (session/target-ip session)
  145. nodes (sort-by compute/hostname (session/nodes-in-group session))
  146. configs (parameter/get-for
  147. session
  148. [:zookeper (keyword (session/group-name session))])
  149. config (configs (keyword target-name))
  150. owner (parameter/get-for session [:zookeeper :owner])
  151. group (parameter/get-for session [:zookeeper :group])]
  152. (->
  153. session
  154. (remote-file/remote-file
  155. (format "%s/zoo.cfg" config-path)
  156. :content (str (string/join
  157. \newline
  158. (map #(format "%s=%s" (name (first %)) (second %))
  159. (merge
  160. default-config
  161. (dissoc config :electionPort :quorumPort))))
  162. \newline
  163. (when (> (count nodes) 1)
  164. (string/join
  165. \newline
  166. (map #(let [config (configs
  167. (keyword (compute/hostname %1)))]
  168. (format "server.%s=%s:%s:%s"
  169. %2
  170. (compute/private-ip %1)
  171. (:quorumPort config 2888)
  172. (:electionPort config 3888)))
  173. nodes
  174. (range 1 (inc (count nodes)))))))
  175. :owner owner :group group :mode "0644")
  176. (remote-file/remote-file
  177. (format "%s/myid" data-path)
  178. :content (str (some #(and (= target-ip (second %)) (first %))
  179. (map #(vector %1 (compute/primary-ip %2))
  180. (range 1 (inc (count nodes)))
  181. nodes)))
  182. :owner owner :group group :mode "0644"))))
  183. (defn store-configuration
  184. "Capture zookeeper configuration"
  185. [session options]
  186. (parameter/update-for
  187. session
  188. [:zookeper (keyword (session/group-name session))]
  189. (fn [m]
  190. (assoc m (session/target-name session) options))))
  191. (defn configure
  192. "Configure zookeeper instance"
  193. [session & {:keys [dataDir tickTime clientPort initLimit syncLimit dataLogDir
  194. electionPort quorumPort]
  195. :or {client-port 2181 quorumPort 2888 electionPort 3888}
  196. :as options}]
  197. (->
  198. session
  199. (store-configuration
  200. (assoc options :quorumPort quorumPort :electionPort electionPort))
  201. (config-files)))
  202. #_
  203. (pallet.core/defnode zk
  204. {}
  205. :bootstrap (pallet.action/phase
  206. (pallet.crate.automated-admin-user/automated-admin-user))
  207. :configure (pallet.action/phase
  208. (pallet.crate.java/java :openjdk :jdk)
  209. (pallet.crate.zookeeper/install)
  210. (pallet.crate.zookeeper/configure)
  211. (pallet.crate.zookeeper/init))
  212. :restart-zookeeper (pallet.action/phase
  213. (pallet.action.service/service
  214. "zookeeper" :action :restart)))