Vagrantfile 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. # -*- mode: ruby -*-
  2. # vi: set ft=ruby :
  3. # This Vagrantfile exists to test packaging. Read more about its use in the
  4. # vagrant section in TESTING.asciidoc.
  5. # Licensed to Elasticsearch under one or more contributor
  6. # license agreements. See the NOTICE file distributed with
  7. # this work for additional information regarding copyright
  8. # ownership. Elasticsearch licenses this file to you under
  9. # the Apache License, Version 2.0 (the "License"); you may
  10. # not use this file except in compliance with the License.
  11. # You may obtain a copy of the License at
  12. #
  13. # http://www.apache.org/licenses/LICENSE-2.0
  14. #
  15. # Unless required by applicable law or agreed to in writing,
  16. # software distributed under the License is distributed on an
  17. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. # KIND, either express or implied. See the License for the
  19. # specific language governing permissions and limitations
  20. # under the License.
  21. define_opts = {
  22. autostart: false
  23. }.freeze
  24. Vagrant.configure(2) do |config|
  25. config.vm.provider 'virtualbox' do |vbox|
  26. # Give the box more memory and cpu because our tests are beasts!
  27. vbox.memory = Integer(ENV['VAGRANT_MEMORY'] || 8192)
  28. vbox.cpus = Integer(ENV['VAGRANT_CPUS'] || 4)
  29. # see https://github.com/hashicorp/vagrant/issues/9524
  30. vbox.customize ["modifyvm", :id, "--audio", "none"]
  31. end
  32. # Switch the default share for the project root from /vagrant to
  33. # /elasticsearch because /vagrant is confusing when there is a project inside
  34. # the elasticsearch project called vagrant....
  35. config.vm.synced_folder '.', '/vagrant', disabled: true
  36. config.vm.synced_folder '.', '/elasticsearch'
  37. # Expose project directory. Note that VAGRANT_CWD may not be the same as Dir.pwd
  38. PROJECT_DIR = ENV['VAGRANT_PROJECT_DIR'] || Dir.pwd
  39. config.vm.synced_folder PROJECT_DIR, '/project'
  40. 'ubuntu-1604'.tap do |box|
  41. config.vm.define box, define_opts do |config|
  42. config.vm.box = 'elastic/ubuntu-16.04-x86_64'
  43. deb_common config, box, extra: <<-SHELL
  44. # Install Jayatana so we can work around it being present.
  45. [ -f /usr/share/java/jayatanaag.jar ] || install jayatana
  46. SHELL
  47. end
  48. end
  49. 'ubuntu-1804'.tap do |box|
  50. config.vm.define box, define_opts do |config|
  51. config.vm.box = 'elastic/ubuntu-18.04-x86_64'
  52. deb_common config, box, extra: <<-SHELL
  53. # Install Jayatana so we can work around it being present.
  54. [ -f /usr/share/java/jayatanaag.jar ] || install jayatana
  55. SHELL
  56. end
  57. end
  58. 'debian-8'.tap do |box|
  59. config.vm.define box, define_opts do |config|
  60. config.vm.box = 'elastic/debian-8-x86_64'
  61. deb_common config, box, extra: <<-SHELL
  62. # this sometimes gets a bad ip, and doesn't appear to be needed
  63. rm -f /etc/apt/sources.list.d/http_debian_net_debian.list
  64. SHELL
  65. end
  66. end
  67. 'debian-9'.tap do |box|
  68. config.vm.define box, define_opts do |config|
  69. config.vm.box = 'elastic/debian-9-x86_64'
  70. deb_common config, box
  71. end
  72. end
  73. 'centos-6'.tap do |box|
  74. config.vm.define box, define_opts do |config|
  75. config.vm.box = 'elastic/centos-6-x86_64'
  76. rpm_common config, box
  77. end
  78. end
  79. 'centos-7'.tap do |box|
  80. config.vm.define box, define_opts do |config|
  81. config.vm.box = 'elastic/centos-7-x86_64'
  82. rpm_common config, box
  83. end
  84. end
  85. 'oel-6'.tap do |box|
  86. config.vm.define box, define_opts do |config|
  87. config.vm.box = 'elastic/oraclelinux-6-x86_64'
  88. rpm_common config, box
  89. end
  90. end
  91. 'oel-7'.tap do |box|
  92. config.vm.define box, define_opts do |config|
  93. config.vm.box = 'elastic/oraclelinux-7-x86_64'
  94. rpm_common config, box
  95. end
  96. end
  97. 'fedora-28'.tap do |box|
  98. config.vm.define box, define_opts do |config|
  99. config.vm.box = 'elastic/fedora-28-x86_64'
  100. dnf_common config, box
  101. end
  102. end
  103. 'fedora-29'.tap do |box|
  104. config.vm.define box, define_opts do |config|
  105. config.vm.box = 'elastic/fedora-28-x86_64'
  106. dnf_common config, box
  107. end
  108. end
  109. 'opensuse-42'.tap do |box|
  110. config.vm.define box, define_opts do |config|
  111. config.vm.box = 'elastic/opensuse-42-x86_64'
  112. suse_common config, box
  113. end
  114. end
  115. 'sles-12'.tap do |box|
  116. config.vm.define box, define_opts do |config|
  117. config.vm.box = 'elastic/sles-12-x86_64'
  118. sles_common config, box
  119. end
  120. end
  121. 'rhel-8'.tap do |box|
  122. config.vm.define box, define_opts do |config|
  123. config.vm.box = 'elastic/rhel-8-x86_64'
  124. rpm_common config, box
  125. end
  126. end
  127. windows_2012r2_box = ENV['VAGRANT_WINDOWS_2012R2_BOX']
  128. if windows_2012r2_box && windows_2012r2_box.empty? == false
  129. 'windows-2012r2'.tap do |box|
  130. config.vm.define box, define_opts do |config|
  131. config.vm.box = windows_2012r2_box
  132. windows_common config, box
  133. end
  134. end
  135. end
  136. windows_2016_box = ENV['VAGRANT_WINDOWS_2016_BOX']
  137. if windows_2016_box && windows_2016_box.empty? == false
  138. 'windows-2016'.tap do |box|
  139. config.vm.define box, define_opts do |config|
  140. config.vm.box = windows_2016_box
  141. windows_common config, box
  142. end
  143. end
  144. end
  145. end
  146. def deb_common(config, name, extra: '')
  147. # http://foo-o-rama.com/vagrant--stdin-is-not-a-tty--fix.html
  148. config.vm.provision 'fix-no-tty', type: 'shell' do |s|
  149. s.privileged = false
  150. s.inline = "sudo sed -i '/tty/!s/mesg n/tty -s \\&\\& mesg n/' /root/.profile"
  151. end
  152. extra_with_lintian = <<-SHELL
  153. #{extra}
  154. install lintian
  155. SHELL
  156. linux_common(
  157. config,
  158. name,
  159. update_command: 'apt-get update',
  160. update_tracking_file: '/var/cache/apt/archives/last_update',
  161. install_command: 'apt-get install -y',
  162. extra: extra_with_lintian
  163. )
  164. end
  165. def rpm_common(config, name)
  166. linux_common(
  167. config,
  168. name,
  169. update_command: 'yum check-update',
  170. update_tracking_file: '/var/cache/yum/last_update',
  171. install_command: 'yum install -y'
  172. )
  173. end
  174. def dnf_common(config, name)
  175. # Autodetect doesn't work....
  176. if Vagrant.has_plugin?('vagrant-cachier')
  177. config.cache.auto_detect = false
  178. config.cache.enable :generic, { :cache_dir => '/var/cache/dnf' }
  179. end
  180. linux_common(
  181. config,
  182. name,
  183. update_command: 'dnf check-update',
  184. update_tracking_file: '/var/cache/dnf/last_update',
  185. install_command: 'dnf install -y',
  186. install_command_retries: 5
  187. )
  188. end
  189. def suse_common(config, name, extra: '')
  190. linux_common(
  191. config,
  192. name,
  193. update_command: 'zypper --non-interactive list-updates',
  194. update_tracking_file: '/var/cache/zypp/packages/last_update',
  195. install_command: 'zypper --non-interactive --quiet install --no-recommends',
  196. extra: extra
  197. )
  198. end
  199. def sles_common(config, name)
  200. extra = <<-SHELL
  201. zypper rr systemsmanagement_puppet puppetlabs-pc1
  202. zypper --non-interactive install git-core
  203. SHELL
  204. suse_common config, name, extra: extra
  205. end
  206. # Configuration needed for all linux boxes
  207. # @param config Vagrant's config object. Required.
  208. # @param name [String] The box name. Required.
  209. # @param update_command [String] The command used to update the package
  210. # manager. Required. Think `apt-get update`.
  211. # @param update_tracking_file [String] The location of the file tracking the
  212. # last time the update command was run. Required. Should be in a place that
  213. # is cached by vagrant-cachier.
  214. # @param install_command [String] The command used to install a package.
  215. # Required. Think `apt-get install #{package}`.
  216. # @param install_command_retries [Integer] Number of times to retry
  217. # a failed install command
  218. # @param extra [String] Additional script to run before installing
  219. # dependencies
  220. #
  221. def linux_common(config,
  222. name,
  223. update_command: 'required',
  224. update_tracking_file: 'required',
  225. install_command: 'required',
  226. install_command_retries: 0,
  227. extra: '')
  228. raise ArgumentError, 'update_command is required' if update_command == 'required'
  229. raise ArgumentError, 'update_tracking_file is required' if update_tracking_file == 'required'
  230. raise ArgumentError, 'install_command is required' if install_command == 'required'
  231. if Vagrant.has_plugin?('vagrant-cachier')
  232. config.cache.scope = :box
  233. end
  234. config.vm.provision 'markerfile', type: 'shell', inline: <<-SHELL
  235. touch /etc/is_vagrant_vm
  236. touch /is_vagrant_vm # for consistency between linux and windows
  237. SHELL
  238. # This prevents leftovers from previous tests using the
  239. # same VM from messing up the current test
  240. config.vm.provision 'clean es installs in tmp', run: 'always', type: 'shell', inline: <<-SHELL
  241. rm -rf /tmp/elasticsearch*
  242. SHELL
  243. sh_set_prompt config, name
  244. sh_install_deps(
  245. config,
  246. update_command,
  247. update_tracking_file,
  248. install_command,
  249. install_command_retries,
  250. extra
  251. )
  252. end
  253. # Sets up a consistent prompt for all users. Or tries to. The VM might
  254. # contain overrides for root and vagrant but this attempts to work around
  255. # them by re-source-ing the standard prompt file.
  256. def sh_set_prompt(config, name)
  257. config.vm.provision 'set prompt', type: 'shell', inline: <<-SHELL
  258. cat \<\<PROMPT > /etc/profile.d/elasticsearch_prompt.sh
  259. export PS1='#{name}:\\w$ '
  260. PROMPT
  261. grep 'source /etc/profile.d/elasticsearch_prompt.sh' ~/.bashrc |
  262. cat \<\<SOURCE_PROMPT >> ~/.bashrc
  263. # Replace the standard prompt with a consistent one
  264. source /etc/profile.d/elasticsearch_prompt.sh
  265. SOURCE_PROMPT
  266. grep 'source /etc/profile.d/elasticsearch_prompt.sh' ~vagrant/.bashrc |
  267. cat \<\<SOURCE_PROMPT >> ~vagrant/.bashrc
  268. # Replace the standard prompt with a consistent one
  269. source /etc/profile.d/elasticsearch_prompt.sh
  270. SOURCE_PROMPT
  271. SHELL
  272. end
  273. def sh_install_deps(config,
  274. update_command,
  275. update_tracking_file,
  276. install_command,
  277. install_command_retries,
  278. extra)
  279. config.vm.provision 'install dependencies', type: 'shell', inline: <<-SHELL
  280. set -e
  281. set -o pipefail
  282. # Retry install command up to $2 times, if failed
  283. retry_installcommand() {
  284. n=0
  285. while true; do
  286. #{install_command} $1 && break
  287. let n=n+1
  288. if [ $n -ge $2 ]; then
  289. echo "==> Exhausted retries to install $1"
  290. return 1
  291. fi
  292. echo "==> Retrying installing $1, attempt $((n+1))"
  293. # Add a small delay to increase chance of metalink providing updated list of mirrors
  294. sleep 5
  295. done
  296. }
  297. installed() {
  298. command -v $1 2>&1 >/dev/null
  299. }
  300. install() {
  301. # Only apt-get update if we haven't in the last day
  302. if [ ! -f #{update_tracking_file} ] || [ "x$(find #{update_tracking_file} -mtime +0)" == "x#{update_tracking_file}" ]; then
  303. echo "==> Updating repository"
  304. #{update_command} || true
  305. touch #{update_tracking_file}
  306. fi
  307. echo "==> Installing $1"
  308. if [ #{install_command_retries} -eq 0 ]
  309. then
  310. #{install_command} $1
  311. else
  312. retry_installcommand $1 #{install_command_retries}
  313. fi
  314. }
  315. ensure() {
  316. installed $1 || install $1
  317. }
  318. #{extra}
  319. installed java || {
  320. echo "==> Java is not installed"
  321. return 1
  322. }
  323. cat \<\<JAVA > /etc/profile.d/java_home.sh
  324. if [ ! -z "\\\$JAVA_HOME" ]; then
  325. export SYSTEM_JAVA_HOME=\\\$JAVA_HOME
  326. unset JAVA_HOME
  327. fi
  328. JAVA
  329. ensure tar
  330. ensure curl
  331. ensure unzip
  332. ensure rsync
  333. installed bats || {
  334. # Bats lives in a git repository....
  335. ensure git
  336. echo "==> Installing bats"
  337. git clone https://github.com/sstephenson/bats /tmp/bats
  338. # Centos doesn't add /usr/local/bin to the path....
  339. /tmp/bats/install.sh /usr
  340. rm -rf /tmp/bats
  341. }
  342. cat \<\<VARS > /etc/profile.d/elasticsearch_vars.sh
  343. export ZIP=/elasticsearch/distribution/zip/build/distributions
  344. export TAR=/elasticsearch/distribution/tar/build/distributions
  345. export RPM=/elasticsearch/distribution/rpm/build/distributions
  346. export DEB=/elasticsearch/distribution/deb/build/distributions
  347. export BATS=/project/build/bats
  348. export BATS_UTILS=/project/build/packaging/bats/utils
  349. export BATS_TESTS=/project/build/packaging/bats/tests
  350. export PACKAGING_ARCHIVES=/project/build/packaging/archives
  351. export PACKAGING_TESTS=/project/build/packaging/tests
  352. VARS
  353. cat \<\<SUDOERS_VARS > /etc/sudoers.d/elasticsearch_vars
  354. Defaults env_keep += "ZIP"
  355. Defaults env_keep += "TAR"
  356. Defaults env_keep += "RPM"
  357. Defaults env_keep += "DEB"
  358. Defaults env_keep += "BATS"
  359. Defaults env_keep += "BATS_UTILS"
  360. Defaults env_keep += "BATS_TESTS"
  361. Defaults env_keep += "PACKAGING_ARCHIVES"
  362. Defaults env_keep += "PACKAGING_TESTS"
  363. Defaults env_keep += "JAVA_HOME"
  364. Defaults env_keep += "SYSTEM_JAVA_HOME"
  365. SUDOERS_VARS
  366. chmod 0440 /etc/sudoers.d/elasticsearch_vars
  367. SHELL
  368. end
  369. def windows_common(config, name)
  370. config.vm.provision 'markerfile', type: 'shell', inline: <<-SHELL
  371. $ErrorActionPreference = "Stop"
  372. New-Item C:/is_vagrant_vm -ItemType file -Force | Out-Null
  373. SHELL
  374. config.vm.provision 'set prompt', type: 'shell', inline: <<-SHELL
  375. $ErrorActionPreference = "Stop"
  376. $ps_prompt = 'function Prompt { "#{name}:$($ExecutionContext.SessionState.Path.CurrentLocation)>" }'
  377. $ps_prompt | Out-File $PsHome/Microsoft.PowerShell_profile.ps1
  378. SHELL
  379. config.vm.provision 'set env variables', type: 'shell', inline: <<-SHELL
  380. $ErrorActionPreference = "Stop"
  381. [Environment]::SetEnvironmentVariable("PACKAGING_ARCHIVES", "C:/project/build/packaging/archives", "Machine")
  382. [Environment]::SetEnvironmentVariable("PACKAGING_TESTS", "C:/project/build/packaging/tests", "Machine")
  383. [Environment]::SetEnvironmentVariable("JAVA_HOME", $null, "Machine")
  384. SHELL
  385. end