Vagrantfile 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. # -*- mode: ruby -*-
  2. # vim: ft=ruby ts=2 sw=2 sts=2 et:
  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. # TODO: make these syncs work for windows!!!
  38. config.vm.synced_folder "#{Dir.home}/.vagrant/gradle/caches/jars-3", "/root/.gradle/caches/jars-3",
  39. create: true,
  40. owner: "vagrant"
  41. config.vm.synced_folder "#{Dir.home}/.vagrant/gradle/caches/modules-2", "/root/.gradle/caches/modules-2",
  42. create: true,
  43. owner: "vagrant"
  44. config.vm.synced_folder "#{Dir.home}/.gradle/wrapper", "/root/.gradle/wrapper",
  45. create: true,
  46. owner: "vagrant"
  47. # Expose project directory. Note that VAGRANT_CWD may not be the same as Dir.pwd
  48. PROJECT_DIR = ENV['VAGRANT_PROJECT_DIR'] || Dir.pwd
  49. config.vm.synced_folder PROJECT_DIR, '/project'
  50. 'ubuntu-1604'.tap do |box|
  51. config.vm.define box, define_opts do |config|
  52. config.vm.box = 'elastic/ubuntu-16.04-x86_64'
  53. deb_common config, box, extra: <<-SHELL
  54. # Install Jayatana so we can work around it being present.
  55. [ -f /usr/share/java/jayatanaag.jar ] || install jayatana
  56. SHELL
  57. ubuntu_docker config
  58. end
  59. end
  60. 'ubuntu-1804'.tap do |box|
  61. config.vm.define box, define_opts do |config|
  62. config.vm.box = 'elastic/ubuntu-18.04-x86_64'
  63. deb_common config, box, extra: <<-SHELL
  64. # Install Jayatana so we can work around it being present.
  65. [ -f /usr/share/java/jayatanaag.jar ] || install jayatana
  66. SHELL
  67. ubuntu_docker config
  68. end
  69. end
  70. 'debian-8'.tap do |box|
  71. config.vm.define box, define_opts do |config|
  72. config.vm.box = 'elastic/debian-8-x86_64'
  73. deb_common config, box, extra: <<-SHELL
  74. # this sometimes gets a bad ip, and doesn't appear to be needed
  75. rm -f /etc/apt/sources.list.d/http_debian_net_debian.list
  76. SHELL
  77. end
  78. end
  79. 'debian-9'.tap do |box|
  80. config.vm.define box, define_opts do |config|
  81. config.vm.box = 'elastic/debian-9-x86_64'
  82. deb_common config, box
  83. deb_docker config
  84. end
  85. end
  86. 'centos-6'.tap do |box|
  87. config.vm.define box, define_opts do |config|
  88. config.vm.box = 'elastic/centos-6-x86_64'
  89. rpm_common config, box
  90. end
  91. end
  92. 'centos-7'.tap do |box|
  93. config.vm.define box, define_opts do |config|
  94. config.vm.box = 'elastic/centos-7-x86_64'
  95. rpm_common config, box
  96. rpm_docker config
  97. end
  98. end
  99. 'oel-6'.tap do |box|
  100. config.vm.define box, define_opts do |config|
  101. config.vm.box = 'elastic/oraclelinux-6-x86_64'
  102. rpm_common config, box
  103. end
  104. end
  105. 'oel-7'.tap do |box|
  106. config.vm.define box, define_opts do |config|
  107. config.vm.box = 'elastic/oraclelinux-7-x86_64'
  108. rpm_common config, box
  109. end
  110. end
  111. 'fedora-28'.tap do |box|
  112. config.vm.define box, define_opts do |config|
  113. config.vm.box = 'elastic/fedora-28-x86_64'
  114. dnf_common config, box
  115. dnf_docker config
  116. end
  117. end
  118. 'fedora-29'.tap do |box|
  119. config.vm.define box, define_opts do |config|
  120. config.vm.box = 'elastic/fedora-29-x86_64'
  121. dnf_common config, box
  122. dnf_docker config
  123. end
  124. end
  125. 'opensuse-42'.tap do |box|
  126. config.vm.define box, define_opts do |config|
  127. config.vm.box = 'elastic/opensuse-42-x86_64'
  128. suse_common config, box
  129. end
  130. end
  131. 'sles-12'.tap do |box|
  132. config.vm.define box, define_opts do |config|
  133. config.vm.box = 'elastic/sles-12-x86_64'
  134. sles_common config, box
  135. end
  136. end
  137. 'rhel-8'.tap do |box|
  138. config.vm.define box, define_opts do |config|
  139. config.vm.box = 'elastic/rhel-8-x86_64'
  140. rpm_common config, box
  141. end
  142. end
  143. windows_2012r2_box = ENV['VAGRANT_WINDOWS_2012R2_BOX']
  144. if windows_2012r2_box && windows_2012r2_box.empty? == false
  145. 'windows-2012r2'.tap do |box|
  146. config.vm.define box, define_opts do |config|
  147. config.vm.box = windows_2012r2_box
  148. windows_common config, box
  149. end
  150. end
  151. end
  152. windows_2016_box = ENV['VAGRANT_WINDOWS_2016_BOX']
  153. if windows_2016_box && windows_2016_box.empty? == false
  154. 'windows-2016'.tap do |box|
  155. config.vm.define box, define_opts do |config|
  156. config.vm.box = windows_2016_box
  157. windows_common config, box
  158. end
  159. end
  160. end
  161. end
  162. def deb_common(config, name, extra: '')
  163. # http://foo-o-rama.com/vagrant--stdin-is-not-a-tty--fix.html
  164. config.vm.provision 'fix-no-tty', type: 'shell' do |s|
  165. s.privileged = false
  166. s.inline = "sudo sed -i '/tty/!s/mesg n/tty -s \\&\\& mesg n/' /root/.profile"
  167. end
  168. extra_with_lintian = <<-SHELL
  169. #{extra}
  170. install lintian
  171. SHELL
  172. linux_common(
  173. config,
  174. name,
  175. update_command: 'apt-get update',
  176. update_tracking_file: '/var/cache/apt/archives/last_update',
  177. install_command: 'apt-get install -y',
  178. extra: extra_with_lintian
  179. )
  180. end
  181. def ubuntu_docker(config)
  182. config.vm.provision 'install Docker using apt', type: 'shell', inline: <<-SHELL
  183. # Install packages to allow apt to use a repository over HTTPS
  184. apt-get install -y \
  185. apt-transport-https \
  186. ca-certificates \
  187. curl \
  188. gnupg2 \
  189. software-properties-common
  190. # Add Docker’s official GPG key
  191. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
  192. # Set up the stable Docker repository
  193. add-apt-repository \
  194. "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
  195. $(lsb_release -cs) \
  196. stable"
  197. # Install Docker. Unlike Fedora and CentOS, this also start the daemon.
  198. apt-get update
  199. apt-get install -y docker-ce docker-ce-cli containerd.io
  200. # Add vagrant to the Docker group, so that it can run commands
  201. usermod -aG docker vagrant
  202. # Enable IPv4 forwarding
  203. sed -i '/net.ipv4.ip_forward/s/^#//' /etc/sysctl.conf
  204. systemctl restart networking
  205. SHELL
  206. end
  207. def deb_docker(config)
  208. config.vm.provision 'install Docker using apt', type: 'shell', inline: <<-SHELL
  209. # Install packages to allow apt to use a repository over HTTPS
  210. apt-get install -y \
  211. apt-transport-https \
  212. ca-certificates \
  213. curl \
  214. gnupg2 \
  215. software-properties-common
  216. # Add Docker’s official GPG key
  217. curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
  218. # Set up the stable Docker repository
  219. add-apt-repository \
  220. "deb [arch=amd64] https://download.docker.com/linux/debian \
  221. $(lsb_release -cs) \
  222. stable"
  223. # Install Docker. Unlike Fedora and CentOS, this also start the daemon.
  224. apt-get update
  225. apt-get install -y docker-ce docker-ce-cli containerd.io
  226. # Add vagrant to the Docker group, so that it can run commands
  227. usermod -aG docker vagrant
  228. SHELL
  229. end
  230. def rpm_common(config, name)
  231. linux_common(
  232. config,
  233. name,
  234. update_command: 'yum check-update',
  235. update_tracking_file: '/var/cache/yum/last_update',
  236. install_command: 'yum install -y'
  237. )
  238. end
  239. def rpm_docker(config)
  240. config.vm.provision 'install Docker using yum', type: 'shell', inline: <<-SHELL
  241. # Install prerequisites
  242. yum install -y yum-utils device-mapper-persistent-data lvm2
  243. # Add repository
  244. yum-config-manager -y --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  245. # Install Docker
  246. yum install -y docker-ce docker-ce-cli containerd.io
  247. # Start Docker
  248. systemctl enable --now docker
  249. # Add vagrant to the Docker group, so that it can run commands
  250. usermod -aG docker vagrant
  251. SHELL
  252. end
  253. def dnf_common(config, name)
  254. # Autodetect doesn't work....
  255. if Vagrant.has_plugin?('vagrant-cachier')
  256. config.cache.auto_detect = false
  257. config.cache.enable :generic, { :cache_dir => '/var/cache/dnf' }
  258. end
  259. linux_common(
  260. config,
  261. name,
  262. update_command: 'dnf check-update',
  263. update_tracking_file: '/var/cache/dnf/last_update',
  264. install_command: 'dnf install -y',
  265. install_command_retries: 5
  266. )
  267. end
  268. def dnf_docker(config)
  269. config.vm.provision 'install Docker using dnf', type: 'shell', inline: <<-SHELL
  270. # Install prerequisites
  271. dnf -y install dnf-plugins-core
  272. # Add repository
  273. dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
  274. # Install Docker
  275. dnf install -y docker-ce docker-ce-cli containerd.io
  276. # Start Docker
  277. systemctl enable --now docker
  278. # Add vagrant to the Docker group, so that it can run commands
  279. usermod -aG docker vagrant
  280. SHELL
  281. end
  282. def suse_common(config, name, extra: '')
  283. linux_common(
  284. config,
  285. name,
  286. update_command: 'zypper --non-interactive list-updates',
  287. update_tracking_file: '/var/cache/zypp/packages/last_update',
  288. install_command: 'zypper --non-interactive --quiet install --no-recommends',
  289. extra: extra
  290. )
  291. end
  292. def sles_common(config, name)
  293. extra = <<-SHELL
  294. zypper rr systemsmanagement_puppet puppetlabs-pc1
  295. zypper --non-interactive install git-core
  296. SHELL
  297. suse_common config, name, extra: extra
  298. end
  299. # Configuration needed for all linux boxes
  300. # @param config Vagrant's config object. Required.
  301. # @param name [String] The box name. Required.
  302. # @param update_command [String] The command used to update the package
  303. # manager. Required. Think `apt-get update`.
  304. # @param update_tracking_file [String] The location of the file tracking the
  305. # last time the update command was run. Required. Should be in a place that
  306. # is cached by vagrant-cachier.
  307. # @param install_command [String] The command used to install a package.
  308. # Required. Think `apt-get install #{package}`.
  309. # @param install_command_retries [Integer] Number of times to retry
  310. # a failed install command
  311. # @param extra [String] Additional script to run before installing
  312. # dependencies
  313. #
  314. def linux_common(config,
  315. name,
  316. update_command: 'required',
  317. update_tracking_file: 'required',
  318. install_command: 'required',
  319. install_command_retries: 0,
  320. extra: '')
  321. raise ArgumentError, 'update_command is required' if update_command == 'required'
  322. raise ArgumentError, 'update_tracking_file is required' if update_tracking_file == 'required'
  323. raise ArgumentError, 'install_command is required' if install_command == 'required'
  324. if Vagrant.has_plugin?('vagrant-cachier')
  325. config.cache.scope = :box
  326. end
  327. config.vm.provision 'markerfile', type: 'shell', inline: <<-SHELL
  328. touch /etc/is_vagrant_vm
  329. touch /is_vagrant_vm # for consistency between linux and windows
  330. SHELL
  331. # This prevents leftovers from previous tests using the
  332. # same VM from messing up the current test
  333. config.vm.provision 'clean es installs in tmp', type: 'shell', inline: <<-SHELL
  334. rm -rf /tmp/elasticsearch*
  335. SHELL
  336. sh_set_prompt config, name
  337. sh_install_deps(
  338. config,
  339. update_command,
  340. update_tracking_file,
  341. install_command,
  342. install_command_retries,
  343. extra
  344. )
  345. end
  346. # Sets up a consistent prompt for all users. Or tries to. The VM might
  347. # contain overrides for root and vagrant but this attempts to work around
  348. # them by re-source-ing the standard prompt file.
  349. def sh_set_prompt(config, name)
  350. config.vm.provision 'set prompt', type: 'shell', inline: <<-SHELL
  351. cat \<\<PROMPT > /etc/profile.d/elasticsearch_prompt.sh
  352. export PS1='#{name}:\\w$ '
  353. PROMPT
  354. grep 'source /etc/profile.d/elasticsearch_prompt.sh' ~/.bashrc |
  355. cat \<\<SOURCE_PROMPT >> ~/.bashrc
  356. # Replace the standard prompt with a consistent one
  357. source /etc/profile.d/elasticsearch_prompt.sh
  358. SOURCE_PROMPT
  359. grep 'source /etc/profile.d/elasticsearch_prompt.sh' ~vagrant/.bashrc |
  360. cat \<\<SOURCE_PROMPT >> ~vagrant/.bashrc
  361. # Replace the standard prompt with a consistent one
  362. source /etc/profile.d/elasticsearch_prompt.sh
  363. SOURCE_PROMPT
  364. SHELL
  365. end
  366. def sh_install_deps(config,
  367. update_command,
  368. update_tracking_file,
  369. install_command,
  370. install_command_retries,
  371. extra)
  372. config.vm.provision 'install dependencies', type: 'shell', inline: <<-SHELL
  373. set -e
  374. set -o pipefail
  375. # Retry install command up to $2 times, if failed
  376. retry_installcommand() {
  377. n=0
  378. while true; do
  379. #{install_command} $1 && break
  380. let n=n+1
  381. if [ $n -ge $2 ]; then
  382. echo "==> Exhausted retries to install $1"
  383. return 1
  384. fi
  385. echo "==> Retrying installing $1, attempt $((n+1))"
  386. # Add a small delay to increase chance of metalink providing updated list of mirrors
  387. sleep 5
  388. done
  389. }
  390. installed() {
  391. command -v $1 2>&1 >/dev/null
  392. }
  393. install() {
  394. # Only apt-get update if we haven't in the last day
  395. if [ ! -f #{update_tracking_file} ] || [ "x$(find #{update_tracking_file} -mtime +0)" == "x#{update_tracking_file}" ]; then
  396. echo "==> Updating repository"
  397. #{update_command} || true
  398. touch #{update_tracking_file}
  399. fi
  400. echo "==> Installing $1"
  401. if [ #{install_command_retries} -eq 0 ]
  402. then
  403. #{install_command} $1
  404. else
  405. retry_installcommand $1 #{install_command_retries}
  406. fi
  407. }
  408. ensure() {
  409. installed $1 || install $1
  410. }
  411. #{extra}
  412. installed java || {
  413. echo "==> Java is not installed"
  414. return 1
  415. }
  416. cat \<\<JAVA > /etc/profile.d/java_home.sh
  417. if [ ! -z "\\\$JAVA_HOME" ]; then
  418. export SYSTEM_JAVA_HOME=\\\$JAVA_HOME
  419. unset JAVA_HOME
  420. fi
  421. JAVA
  422. ensure tar
  423. ensure curl
  424. ensure unzip
  425. ensure rsync
  426. ensure expect
  427. installed bats || {
  428. # Bats lives in a git repository....
  429. ensure git
  430. echo "==> Installing bats"
  431. git clone https://github.com/sstephenson/bats /tmp/bats
  432. # Centos doesn't add /usr/local/bin to the path....
  433. /tmp/bats/install.sh /usr
  434. rm -rf /tmp/bats
  435. }
  436. cat \<\<VARS > /etc/profile.d/elasticsearch_vars.sh
  437. export ZIP=/elasticsearch/distribution/zip/build/distributions
  438. export TAR=/elasticsearch/distribution/tar/build/distributions
  439. export RPM=/elasticsearch/distribution/rpm/build/distributions
  440. export DEB=/elasticsearch/distribution/deb/build/distributions
  441. export PACKAGING_TESTS=/project/build/packaging/tests
  442. VARS
  443. cat \<\<SUDOERS_VARS > /etc/sudoers.d/elasticsearch_vars
  444. Defaults env_keep += "ZIP"
  445. Defaults env_keep += "TAR"
  446. Defaults env_keep += "RPM"
  447. Defaults env_keep += "DEB"
  448. Defaults env_keep += "PACKAGING_ARCHIVES"
  449. Defaults env_keep += "PACKAGING_TESTS"
  450. Defaults env_keep += "BATS_UTILS"
  451. Defaults env_keep += "BATS_TESTS"
  452. Defaults env_keep += "JAVA_HOME"
  453. Defaults env_keep += "SYSTEM_JAVA_HOME"
  454. SUDOERS_VARS
  455. chmod 0440 /etc/sudoers.d/elasticsearch_vars
  456. SHELL
  457. end
  458. def windows_common(config, name)
  459. config.vm.provision 'markerfile', type: 'shell', inline: <<-SHELL
  460. $ErrorActionPreference = "Stop"
  461. New-Item C:/is_vagrant_vm -ItemType file -Force | Out-Null
  462. SHELL
  463. config.vm.provision 'set prompt', type: 'shell', inline: <<-SHELL
  464. $ErrorActionPreference = "Stop"
  465. $ps_prompt = 'function Prompt { "#{name}:$($ExecutionContext.SessionState.Path.CurrentLocation)>" }'
  466. $ps_prompt | Out-File $PsHome/Microsoft.PowerShell_profile.ps1
  467. SHELL
  468. config.vm.provision 'set env variables', type: 'shell', inline: <<-SHELL
  469. $ErrorActionPreference = "Stop"
  470. [Environment]::SetEnvironmentVariable("PACKAGING_ARCHIVES", "C:/project/build/packaging/archives", "Machine")
  471. [Environment]::SetEnvironmentVariable("PACKAGING_TESTS", "C:/project/build/packaging/tests", "Machine")
  472. [Environment]::SetEnvironmentVariable("JAVA_HOME", $null, "Machine")
  473. SHELL
  474. end