Skip to content

Instantly share code, notes, and snippets.

@glerchundi
Last active August 29, 2015 14:00
Show Gist options
  • Save glerchundi/11224832 to your computer and use it in GitHub Desktop.
Save glerchundi/11224832 to your computer and use it in GitHub Desktop.
Simple script to wrap vagrant into a blocking command (to use it inside with launchctl).
# coreos-vagrant is configured through a series of configuration
# options (global ruby variables) which are detailed below. To modify
# these options, first copy this file to "config.rb". Then simply
# uncomment the necessary lines, leaving the $, and replace everything
# after the equals sign..
# Size of the CoreOS cluster created by Vagrant
$num_instances=1
# Log the serial consoles of CoreOS VMs to log/
# Enable by setting value to true, disable with false
$enable_serial_logging=false
# Setting for VirtualBox VMs
$vb_gui = false
$vb_memory = 2048
$vb_cpus = 1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>org.itspunchy.vagrant.ci-server</string>
<key>ProgramArguments</key>
<array>
<string>bash</string>
<string>-c</string>
<string>
echo 'umounting disks...';
for disk in $(mount | grep /Volumes/ | awk '{ print $1; }'); do diskutil umountDisk $disk; done;
echo 'unloading usb mass storage extension...';
#kextunload /System/Library/Extensions/AppleUSBCardReader.kext;
kextunload /System/Library/Extensions/IOUSBMassStorageClass.kext;
echo 'launching vagrant...';
PWD=`pwd`; PID=`sudo -i -u gip "cd $PWD; /usr/local/bin/vagrant-launchctl"`;
echo 'loading usb mass storage extension back...';
kextload /System/Library/Extensions/IOUSBMassStorageClass.kext;
#kextload /System/Library/Extensions/AppleUSBCardReader.kext;
/usr/local/bin/waitpid $PID;
</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>/Users/gip/Downloads/coreos-vagrant</string>
</dict>
</plist>
# -*- mode: ruby -*-
# # vi: set ft=ruby :
# NOTE: This monkey-patching of the coreos guest plugin is a terrible
# hack that needs to be removed once the upstream plugin works with
# alpha CoreOS images.
require 'tempfile'
require 'ipaddr'
require Vagrant.source_root.join("plugins/guests/coreos/cap/configure_networks.rb")
BASE_CLOUD_CONFIG = <<EOF
#cloud-config
coreos:
units:
- name: coreos-cloudinit-vagrant-user.path
command: start
runtime: no
content: |
[Path]
PathExists=/var/lib/coreos-vagrant/vagrantfile-user-data
- name: coreos-cloudinit-vagrant-user.service
runtime: no
content: |
[Unit]
ConditionFileNotEmpty=/var/lib/coreos-vagrant/vagrantfile-user-data
[Service]
Type=oneshot
EnvironmentFile=/etc/environment
ExecStart=/usr/bin/coreos-cloudinit --from-file /var/lib/coreos-vagrant/vagrantfile-user-data
RemainAfterExit=yes
EOF
NETWORK_UNIT = <<EOF
- name: %s
runtime: no
content: |
[Match]
Name=%s
[Network]
Address=%s
EOF
# Borrowed from http://stackoverflow.com/questions/1825928/netmask-to-cidr-in-ruby
IPAddr.class_eval do
def to_cidr
self.to_i.to_s(2).count("1")
end
end
module VagrantPlugins
module GuestCoreOS
module Cap
class ConfigureNetworks
include Vagrant::Util
def self.configure_networks(machine, networks)
cfg = BASE_CLOUD_CONFIG
machine.communicate.tap do |comm|
# Read network interface names
interfaces = []
comm.sudo("ifconfig | grep enp0 | cut -f1 -d:") do |_, result|
interfaces = result.split("\n")
end
ip = ""
# Configure interfaces
# FIXME: fix matching of interfaces with IP adresses
networks.each do |network|
iface_num = network[:interface].to_i
iface_name = interfaces[iface_num]
cidr = IPAddr.new('255.255.255.0').to_cidr
address = "%s/%s" % [network[:ip], cidr]
unit_name = "50-%s.network" % [iface_name]
unit = NETWORK_UNIT % [unit_name, iface_name, address]
cfg = "#{cfg}#{unit}"
ip = network[:ip]
end
cfg = <<EOF
#{cfg}
write_files:
- path: /etc/environment
content: |
COREOS_PUBLIC_IPV4=#{ip}
COREOS_PRIVATE_IPV4=#{ip}
hostname: #{machine.name}
EOF
temp = Tempfile.new("coreos-vagrant")
temp.binmode
temp.write(cfg)
temp.close
comm.upload(temp.path, "/tmp/user-data")
comm.sudo("mkdir -p /var/lib/coreos-vagrant")
comm.sudo("mv /tmp/user-data /var/lib/coreos-vagrant/")
end
end
end
class ChangeHostName
def self.change_host_name(machine, name)
# This is handled in configure_networks
end
end
end
end
end
#cloud-config
write_files:
- path: /opt/bin/dockerctl
permissions: 0755
content: |
#!/bin/bash
DOCKER_BIN=/usr/bin/docker
function _split_image_n_tag {
local image_n_tag="$1"
[[ -z "$image_n_tag" ]] && exit 1;
IFS=':' read -ra values <<< "$image_n_tag"
[[ -z "${values[0]}" ]] && exit 1;
[[ -z "${values[1]}" ]] && values[1]="latest";
echo "${values[0]} ${values[1]}"
}
function _docker_cleanup {
$DOCKER_BIN rm $($DOCKER_BIN ps -a -q)
$DOCKER_BIN rmi $($DOCKER_BIN images | grep "^<none>" | awk "{print $3}" | tr -s ' ' | cut -d ' ' -f 3)
}
function start {
local name=$1
shift 1
$DOCKER_BIN start -a $name || $DOCKER_BIN run --name $name $@
}
function stop {
local name=$1
$DOCKER_BIN stop $name
}
function build {
local path="$1"
[[ -z "$path" ]] && echo "Provide a path." && exit 1;
local image_n_tag=$(cat $path/Dockerfile | head -n 1 | awk '/# Image:/{ print $3 }')
[[ -z "$image_n_tag" ]] && echo "Dockerfile's first line should be: '# Image: <image_and_tag>.'" && exit 1;
$DOCKER_BIN build -t $image_n_tag $path/
}
function pull {
local image_n_tag="$1"
local repository="$2"
if [ -z "$repository" ]; then
$DOCKER_BIN pull $image_n_tag
else
local uri=$repository/$image_n_tag
$DOCKER_BIN pull $uri
$DOCKER_BIN tag $uri $image_n_tag
$DOCKER_BIN rmi $uri
fi
}
function push {
local image_n_tag="$1"
local image_n_tag_parts=($(_split_image_n_tag $image_n_tag))
local repository="$2"
[[ -z "$repository" ]] && repository="localhost:5000";
$DOCKER_BIN tag $image_n_tag $repository/$image_n_tag
$DOCKER_BIN push $repository/${image_n_tag_parts[0]}
$DOCKER_BIN rmi $repository/$image_n_tag
}
case "$1" in
start)
shift 1
start $@
;;
stop)
shift 1
stop $@
;;
build)
shift 1
build $@
;;
pull)
shift 1
pull $@
;;
push)
shift 1
push $@
;;
*)
;;
esac
exit 0
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCpwctyjHEfsV5ns/PvauqQzYQwzPU4Vtt3PT6B+PhkxL9bxhp5/ElawC8yFKNR+7XOeP90mGzemUw6Lv4vmiv7KPSaJJqYlF/KkJVFPP7nC8B6jMr0zW0U6NaQEprMDAbBFDOTYiyVjQ1/00tWmy32sZ8ESv/8kqUQt9xX0R+Q0HbECeydUpBieDfLxn5/jjXK5qlFlCq/uvKRulhFfjMNcUVNEmtHTafgGz7XIJVw2oLu3j4/l2TSjZxNT0X974tLjym0IlucFp7akVaXPmYx+VUBU5/D5gKpg7mNdijbxA3lCIlI1RpRDSl0QIKiZypZNkB/7Ugmln4NFztf7m/t glertxundi@gmail.com
coreos:
units:
- name: media-data.service
command: start
content: |
[Unit]
Description=Mount data on /media/data
DefaultDependencies=no
Wants=media.mount
After=media.mount
Conflicts=umount.target
ConditionPathIsMountPoint=!/media/data
[Service]
RemainAfterExit=no
Restart=always
RestartSec=10s
ExecStartPre=/bin/mkdir -p /media/data
ExecStart=/bin/mount -o loop /home/core/share/core-01.drive /media/data
[Install]
WantedBy=multi-user.target
- name: registry.service
command: start
content: |
[Unit]
Description=Docker Registry Service
After=docker.service
Requires=docker.service
After=media-data.service
Requires=media-data.service
[Service]
TimeoutStartSec=600s
Restart=always
RestartSec=10s
ExecStartPre=/opt/bin/dockerctl pull registry:0.6.8
ExecStart=/opt/bin/dockerctl start registry \
-p 5000:5000 \
-v /media/data/docker-registry:/registry \
-e DOCKER_REGISTRY_CONFIG=/registry/config.yml \
-e SETTINGS_FLAVOR=dev \
-e SECRET_KEY=k7yMvFXGvHhezkqnRVFDKp65RqzkxgHC8kVGujRXGVD7Eu76JkntT69LTPdLLEFw \
registry:0.6.8
ExecStop=/opt/bin/dockerctl stop registry
[Install]
WantedBy=multi-user.target
- name: database.service
command: start
content: |
[Unit]
Description=PostgresSQL Database Service
After=registry.service
Requires=registry.service
[Service]
TimeoutStartSec=600s
Restart=always
RestartSec=10s
ExecStartPre=/opt/bin/dockerctl pull glerchundi/postgresql:9.3 localhost:5000
ExecStart=/bin/bash -c " \
authorized_keys=$(base64 --wrap=0 /home/core/.ssh/authorized_keys); \
/opt/bin/dockerctl start postgresql \
-p :22 \
-p 5432:5432 \
-v /media/data/postgresql:/var/lib/postgresql \
-e SSH_AUTHORIZED_KEYS=$authorized_keys \
glerchundi/postgresql:9.3 \
"
ExecStop=/opt/bin/dockerctl stop postgresql
[Install]
WantedBy=multi-user.target
- name: atlassian-stash.service
command: start
content: |
[Unit]
Description=Atlassian Stash Service
After=database.service
Requires=database.service
[Service]
TimeoutStartSec=600s
Restart=always
RestartSec=10s
ExecStartPre=/opt/bin/dockerctl pull glerchundi/atlassian-stash:2.12.2 localhost:5000
ExecStart=/bin/bash -c " \
authorized_keys=$(base64 --wrap=0 /home/core/.ssh/authorized_keys); \
/opt/bin/dockerctl start atlassian-stash \
--link postgresql:pg \
-p :22 \
-p 7990:7990 \
-v /media/data/atlassian-stash:/home/stash \
-e SSH_AUTHORIZED_KEYS=$authorized_keys \
glerchundi/atlassian-stash:2.12.2 \
"
ExecStop=/opt/bin/dockerctl stop atlassian-stash
[Install]
WantedBy=multi-user.target
#!/bin/sh
VAGRANT_BIN=/usr/bin/vagrant
function get_name_and_provider() {
echo $($VAGRANT_BIN status | grep 'running (' | awk '{print $1,$3; }' | sed 's/(//g' | sed 's/)//g')
}
function is_running() {
local running=false
local res=($(get_name_and_provider))
if [ "${#res[@]}" -eq "2" ]; then
running=true
fi
echo $running
}
if [ ! -f ./Vagrantfile ]; then
echo "Vagrantfile does not exist in ./Vagrantfile!"
exit 1
fi
if [ $(is_running) = false ] ; then
$VAGRANT_BIN up
fi
NAME_AND_PROVIDER=($(get_name_and_provider))
NAME=${NAME_AND_PROVIDER[0]}
PROVIDER=${NAME_AND_PROVIDER[1]}
MACHINE_ID=$(cat .vagrant/machines/$NAME/$PROVIDER/id)
PID=$(ps x | grep $MACHINE_ID | grep -v 'grep' | awk '{ print $1; }')
echo $PID
# -*- mode: ruby -*-
# # vi: set ft=ruby :
require 'fileutils'
require_relative 'override-plugin.rb'
CLOUD_CONFIG_PATH = "./user-data"
CONFIG= "config.rb"
# Defaults for config options defined in CONFIG
$num_instances = 1
$enable_serial_logging = false
$vb_gui = false
$vb_memory = 1024
$vb_cpus = 1
# Attempt to apply the deprecated environment variable NUM_INSTANCES to
# $num_instances while allowing config.rb to override it
if ENV["NUM_INSTANCES"].to_i > 0 && ENV["NUM_INSTANCES"]
$num_instances = ENV["NUM_INSTANCES"].to_i
end
if File.exist?(CONFIG)
require_relative CONFIG
end
Vagrant.configure("2") do |config|
config.vm.box = "coreos-alpha"
config.vm.box_url = "http://storage.core-os.net/coreos/amd64-usr/alpha/coreos_production_vagrant.box"
config.vm.provider :vmware_fusion do |vb, override|
override.vm.box_url = "http://storage.core-os.net/coreos/amd64-usr/alpha/coreos_production_vagrant_vmware_fusion.box"
end
# Fix docker not being able to resolve private registry in VirtualBox
config.vm.provider :virtualbox do |vb, override|
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
vb.customize ['modifyvm', :id, '--usb', 'on']
vb.customize ['usbfilter', 'add', '0', '--target', :id, '--name', 'convoyxl', '--vendorid', '0x1a4a', '--productid', '0x1670']
end
# plugin conflict
if Vagrant.has_plugin?("vagrant-vbguest") then
config.vbguest.auto_update = false
end
(1..$num_instances).each do |i|
config.vm.define vm_name = "core-%02d" % i do |config|
config.vm.hostname = vm_name
if $enable_serial_logging
logdir = File.join(File.dirname(__FILE__), "log")
FileUtils.mkdir_p(logdir)
serialFile = File.join(logdir, "%s-serial.txt" % vm_name)
FileUtils.touch(serialFile)
config.vm.provider :vmware_fusion do |v, override|
v.vmx["serial0.present"] = "TRUE"
v.vmx["serial0.fileType"] = "file"
v.vmx["serial0.fileName"] = serialFile
v.vmx["serial0.tryNoRxLoss"] = "FALSE"
end
config.vm.provider :virtualbox do |vb, override|
vb.customize ["modifyvm", :id, "--uart1", "0x3F8", "4"]
vb.customize ["modifyvm", :id, "--uartmode1", serialFile]
end
end
config.vm.provider :virtualbox do |vb|
vb.gui = $vb_gui
vb.memory = $vb_memory
vb.cpus = $vb_cpus
end
ip = "172.17.8.#{i+100}"
config.vm.network :private_network, ip: ip
# Uncomment below to enable NFS for sharing the host machine into the coreos-vagrant VM.
config.vm.synced_folder ".", "/home/core/share", id: "core", :nfs => true, :mount_options => ['nolock,vers=3,udp']
if File.exist?(CLOUD_CONFIG_PATH)
config.vm.provision :file, :source => "#{CLOUD_CONFIG_PATH}", :destination => "/tmp/vagrantfile-user-data"
config.vm.provision :shell, :inline => "mv /tmp/vagrantfile-user-data /var/lib/coreos-vagrant/", :privileged => true
end
end
end
end
#!/bin/sh
pid=$1
if [ -z "$pid" ]; then
echo "PID is required as an argument" >&2
exit 1
fi
name=$(ps -p $pid -o comm=)
if [ $? -eq 0 ]; then
echo "Waiting for PID $pid to finish ($name)"
while ps -p $pid > /dev/null; do sleep 1; done;
else
echo "Failed to find process with PID $pid" >&2
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment