---
layout: null
---
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Size of the cluster created by Vagrant
num_instances = 2

# VM Basename
instance_name_prefix="calico"

# Version of mesos to install from official mesos repo
mesos_version = "1.1.0"

# Download URL for Mesos DNS.
mesos_dns_url = "https://github.com/mesosphere/mesos-dns/releases/download/v0.5.0/mesos-dns-v0.5.0-linux-amd64"

# The calicoctl download URL.
calicoctl_url = "{{site.data.versions[page.version].first.components.calicoctl.download_url}}"

# The version of the calico docker images to install.  This is used to pre-load
# the calico/node image which slows down the install process, but speeds up the tutorial.
#
# This version should match the version required by calicoctl installed from
# calicoctl_url.
calico_node_ver = "{{site.data.versions[page.version].first.components["calico/node"].version}}"

# Script to write out the Calico environment file.
$write_calico_env=<<SCRIPT
cat <<EOF > /etc/sysconfig/calico
ETCD_ENDPOINTS=http://${1}:2379
ETCD_CA_FILE=""
ETCD_CERT_FILE=""
ETCD_KEY_FILE=""
EOF
SCRIPT

$write_marathon_env=<<SCRIPT
cat <<EOF > /etc/sysconfig/calico
ETCD_ENDPOINTS=http://${1}:2379
ETCD_CA_FILE=""
ETCD_CERT_FILE=""
ETCD_KEY_FILE=""
EOF
SCRIPT

# Script to write out the Mesos DNS config file.
$write_mesos_dns_config=<<SCRIPT
cat <<EOF > /etc/sysconfig/mesos-dns
{
  "zk": "",
  "masters": ["${1}:5050"],
  "refreshSeconds": 5,
  "ttl": 60,
  "domain": "mesos",
  "port": 53,
  "resolvers": ["8.8.8.8"],
  "timeout": 5,
  "httpon": true,
  "dsnon": true,
  "httpport": 8123,
  "externalon": true,
  "listener": "0.0.0.0",
  "SOAMname": "root.ns1.mesos",
  "SOARname": "ns1.mesos",
  "SOARefresh": 60,
  "SOARetry":   600,
  "SOAExpire":  86400,
  "SOAMinttl": 60,
  "IPSources": ["netinfo", "mesos", "host"]
}
EOF
SCRIPT

$write_cni_conf=<<SCRIPT
cat <<EOF > /etc/cni/net.d/calico.conf
{
   "name": "calico",
   "cniVersion": "0.1.0",
   "type": "calico",
   "ipam": {
       "type": "calico-ipam"
   },
   "etcd_endpoints": "http://master.mesos:2379"
}
EOF
SCRIPT

Vagrant.configure("2") do |config|
  config.vm.box = 'centos/7'

  # The vagrant centos:7 box has a bug where it automatically tries to sync /home/vagrant/sync using rsync, so disable it:
  # https://github.com/mitchellh/vagrant/issues/6154#issuecomment-135949010
  config.vm.synced_folder ".", "/home/vagrant/sync", disabled: true

  config.vm.provider :virtualbox do |vbox|
    # On VirtualBox, we don't have guest additions or a functional vboxsf
    # in CoreOS, so tell Vagrant that so it can be smarter.
    vbox.functional_vboxsf = false
    vbox.check_guest_additions = false
    vbox.memory = 2048
    vbox.cpus = 1.5
  end

  master_ip = "172.24.197.101"

  # Set up each box
  (1..num_instances).each do |i|
    vm_name = "%s-%02d" % [instance_name_prefix, i]
    config.vm.define vm_name do |host|
      # Provision the FQDN
      host.vm.hostname = vm_name

      # Assign IP and prepend IP/hostname pair to /etc/hosts for correct FQDN IP resolution
      ip = "172.24.197.#{i+100}"
      host.vm.network :private_network, ip: ip

      # Selinux => permissive
      host.vm.provision :shell, inline: "setenforce permissive"

      # Install docker here, as otherwise it will run 'yum update' and unexpectedly ugrade mesos
      host.vm.provision :docker

      # Add official Mesos Repos and install Mesos.
      host.vm.provision :shell, inline: "sudo rpm -Uvh http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-3.noarch.rpm"
      # Intsall net-tools for ifconfig, which mesos depends on for CNI
      host.vm.provision :shell, inline: "yum -y install net-tools mesos-#{mesos_version}"

      # Write out the Calico environment file.
      host.vm.provision :shell, inline: $write_calico_env, args: "#{master_ip}"

      # Master
      if i == 1
        host.vm.provision :shell, inline: "yum -y install mesosphere-zookeeper etcd marathon"

        # Zookeeper
        host.vm.provision :shell, inline: "systemctl start zookeeper"

        # Mesos-Master
        host.vm.provision :shell, inline: "sh -c 'echo #{master_ip} > /etc/mesos-master/hostname'"
        host.vm.provision :shell, inline: "sh -c 'echo #{ip} > /etc/mesos-master/ip'"
        host.vm.provision :shell, inline: "systemctl start mesos-master"

        # Marathon
        host.vm.provision :shell, inline: "systemctl start marathon"

        # etcd
        host.vm.provision :shell, inline: "sh -c 'echo ETCD_LISTEN_CLIENT_URLS=\"http://0.0.0.0:2379\" >> /etc/etcd/etcd.conf'"
        host.vm.provision :shell, inline: "sh -c 'echo ETCD_ADVERTISE_CLIENT_URLS=\"http://#{master_ip}:2379\" >> /etc/etcd/etcd.conf'"
        host.vm.provision :shell, inline: "systemctl enable etcd.service"
        host.vm.provision :shell, inline: "systemctl start etcd.service"

        # Mesos-dns
        host.vm.provision :shell, inline: "curl -o /usr/bin/mesos-dns -L #{mesos_dns_url}", :privileged => true
        host.vm.provision :shell, inline: "chmod +x /usr/bin/mesos-dns"
        host.vm.provision :shell, inline: $write_mesos_dns_config, args: "#{master_ip}"
        host.vm.provision "file", source: "mesos-dns.service", destination: "/tmp/mesos-dns.service"
        host.vm.provision :shell, inline: "mv /tmp/mesos-dns.service /usr/lib/systemd/system/mesos-dns.service"
        host.vm.provision :shell, inline: "systemctl start mesos-dns"
      end

      # Configure all hosts to use Mesos DNS.  Do this after configuring Mesos DNS
      # but before starting Calico on the agent because restarting network services
      # also resets IP forwarding.
      host.vm.provision :shell, inline: "sh -c 'echo DNS1=#{master_ip} >> /etc/sysconfig/network-scripts/ifcfg-eth1'"
      host.vm.provision :shell, inline: "sh -c 'echo PEERDNS=yes >> /etc/sysconfig/network-scripts/ifcfg-eth1'"
      host.vm.provision :shell, inline: "systemctl restart network"

      # Provision with docker, and download the calico-node docker image
      host.vm.provision :docker, images: [
	        "quay.io/calico/node:#{calico_node_ver}",
      ]

      # Configure docker to use etcd on master as its datastore
      host.vm.provision :shell, inline: "mkdir -p /etc/docker/"
      host.vm.provision :shell, inline: %Q(echo '{\"cluster-store\":\"etcd://#{master_ip}\:2379"}' > /etc/docker/daemon.json)
      host.vm.provision :shell, inline: "systemctl restart docker.service"

      # Install calicoctl
      host.vm.provision :shell, inline: "curl -o /usr/bin/calicoctl -L #{calicoctl_url}", :privileged => true
      host.vm.provision :shell, inline: "chmod +x /usr/bin/calicoctl"

      # Install the Calico service files and start the Calico services.
      host.vm.provision "file", source: "calico.service", destination: "/tmp/calico.service"
      host.vm.provision :shell, inline: "mv /tmp/calico.service /usr/lib/systemd/system/calico.service"
      host.vm.provision :shell, inline: "systemctl start calico"

      if i == 1
        # Master specific stuff.
        # Setup marathon-lb
        host.vm.provision :docker, images: ["mesosphere/marathon-lb:v1.4.3"]
        host.vm.provision "file", source: "marathon-lb.service", destination: "/tmp/marathon-lb.service"
        host.vm.provision :shell, inline: "sh -c 'echo MARATHON_IP=#{master_ip} > /etc/sysconfig/marathon-lb'"
        host.vm.provision :shell, inline: "mv /tmp/marathon-lb.service /usr/lib/systemd/system/marathon-lb.service"
        host.vm.provision :shell, inline: "systemctl start marathon-lb"
      end

      # Configure and start mesos-slave
      host.vm.provision :shell, inline: "sh -c 'echo zk://#{master_ip}:2181/mesos > /etc/mesos/zk'"
      # NOTE: Saving the IP below is used for demo purposes to workaround DNS hostname
      # resolution when visiting the Mesos Master UI agent sandboxes.
      host.vm.provision :shell, inline: "sh -c 'echo #{ip} > /etc/mesos-slave/ip'"
      host.vm.provision :shell, inline: "sh -c 'echo #{ip} > /etc/mesos-slave/hostname'"
      host.vm.provision :shell, inline: "sh -c 'echo mesos,docker > /etc/mesos-slave/containerizers'"
      host.vm.provision :shell, inline: "sh -c 'echo docker > /etc/mesos-slave/image_providers'"
      host.vm.provision :shell, inline: "sh -c 'echo filesystem/linux,docker/runtime > /etc/mesos-slave/isolation'"
      host.vm.provision :shell, inline: "mkdir -p /etc/cni/net.d"
      host.vm.provision :shell, inline: $write_cni_conf
      host.vm.provision :shell, inline: "sh -c 'echo /etc/cni/net.d/ > /etc/mesos-slave/network_cni_config_dir'"
      host.vm.provision :shell, inline: "mkdir -p /opt/cni/bin"
      host.vm.provision :shell, inline: "curl -L -o /opt/cni/bin/calico {{site.data.versions[page.version].first.components["calico/cni"].download_calico_url}}"
      host.vm.provision :shell, inline: "curl -L -o /opt/cni/bin/calico-ipam {{site.data.versions[page.version].first.components["calico/cni"].download_calico_ipam_url}}"
      host.vm.provision :shell, inline: "chmod +x /opt/cni/bin/*"
      host.vm.provision :shell, inline: "sh -c 'echo /opt/cni/bin/ > /etc/mesos-slave/network_cni_plugins_dir'"


      host.vm.provision :shell, inline: "systemctl start mesos-slave.service"
    end
  end
end
