Merge pull request #247 from Mirantis/bootstrap-images

Add option to boot slave using pxe into bootstrap image
This commit is contained in:
Łukasz Oleś 2015-10-13 10:40:22 +02:00
commit b407d83941
7 changed files with 198 additions and 12 deletions

59
Vagrantfile vendored
View File

@ -39,6 +39,10 @@ SYNC_TYPE = cfg["sync_type"]
MASTER_CPUS = cfg["master_cpus"] MASTER_CPUS = cfg["master_cpus"]
SLAVES_CPUS = cfg["slaves_cpus"] SLAVES_CPUS = cfg["slaves_cpus"]
PARAVIRT_PROVIDER = cfg.fetch('paravirtprovider', false) PARAVIRT_PROVIDER = cfg.fetch('paravirtprovider', false)
PREPROVISIONED = cfg.fetch('preprovisioned', true)
# Initialize noop plugins only in case of PXE boot
require_relative 'bootstrap/vagrant_plugins/noop' unless PREPROVISIONED
def ansible_playbook_command(filename, args=[]) def ansible_playbook_command(filename, args=[])
"ansible-playbook -v -i \"localhost,\" -c local /vagrant/bootstrap/playbooks/#{filename} #{args.join ' '}" "ansible-playbook -v -i \"localhost,\" -c local /vagrant/bootstrap/playbooks/#{filename} #{args.join ' '}"
@ -52,6 +56,9 @@ master_celery = ansible_playbook_command("celery.yaml", ["--skip-tags", "slave"]
slave_celery = ansible_playbook_command("celery.yaml", ["--skip-tags", "master"]) slave_celery = ansible_playbook_command("celery.yaml", ["--skip-tags", "master"])
master_pxe = ansible_playbook_command("pxe.yaml")
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define "solar-dev", primary: true do |config| config.vm.define "solar-dev", primary: true do |config|
@ -59,6 +66,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.provision "shell", inline: solar_script, privileged: true config.vm.provision "shell", inline: solar_script, privileged: true
config.vm.provision "shell", inline: master_celery, privileged: true config.vm.provision "shell", inline: master_celery, privileged: true
config.vm.provision "shell", inline: master_pxe, privileged: true unless PREPROVISIONED
config.vm.provision "file", source: "~/.vagrant.d/insecure_private_key", destination: "/vagrant/tmp/keys/ssh_private" config.vm.provision "file", source: "~/.vagrant.d/insecure_private_key", destination: "/vagrant/tmp/keys/ssh_private"
config.vm.provision "file", source: "bootstrap/ansible.cfg", destination: "/home/vagrant/.ansible.cfg" config.vm.provision "file", source: "bootstrap/ansible.cfg", destination: "/home/vagrant/.ansible.cfg"
config.vm.network "private_network", ip: "10.0.0.2" config.vm.network "private_network", ip: "10.0.0.2"
@ -101,17 +109,31 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
index = i + 1 index = i + 1
ip_index = i + 3 ip_index = i + 3
config.vm.define "solar-dev#{index}" do |config| config.vm.define "solar-dev#{index}" do |config|
# standard box with all stuff preinstalled
config.vm.box = SLAVES_IMAGE
config.vm.provision "file", source: "bootstrap/ansible.cfg", destination: "/home/vagrant/.ansible.cfg" # Standard box with all stuff preinstalled
config.vm.provision "shell", inline: slave_script, privileged: true config.vm.box = SLAVES_IMAGE
config.vm.provision "shell", inline: solar_script, privileged: true
config.vm.provision "shell", inline: slave_celery, privileged: true
config.vm.network "private_network", ip: "10.0.0.#{ip_index}"
config.vm.host_name = "solar-dev#{index}" config.vm.host_name = "solar-dev#{index}"
if PREPROVISIONED
config.vm.provision "file", source: "bootstrap/ansible.cfg", destination: "/home/vagrant/.ansible.cfg"
config.vm.provision "shell", inline: slave_script, privileged: true
config.vm.provision "shell", inline: solar_script, privileged: true
config.vm.provision "shell", inline: slave_celery, privileged: true
config.vm.network "private_network", ip: "10.0.0.#{ip_index}"
else
# Disable attempts to install guest os and check that node is booted using ssh,
# because nodes will have ip addresses from dhcp, and vagrant doesn't know
# which ip to use to perform connection
config.vm.communicator = :noop
config.vm.guest = :noop_guest
# Configure network to boot vm using pxe
config.vm.network "private_network", adapter: 1, ip: "10.0.0.#{ip_index}"
config.vbguest.no_install = true
config.vbguest.auto_update = false
end
config.vm.provider :virtualbox do |v| config.vm.provider :virtualbox do |v|
boot_order(v, ['net', 'disk'])
v.customize [ v.customize [
"modifyvm", :id, "modifyvm", :id,
"--memory", SLAVES_RAM, "--memory", SLAVES_RAM,
@ -133,14 +155,27 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
libvirt.volume_cache = 'unsafe' libvirt.volume_cache = 'unsafe'
end end
if SYNC_TYPE == 'nfs' if PREPROVISIONED
config.vm.synced_folder ".", "/vagrant", type: "nfs" if SYNC_TYPE == 'nfs'
end config.vm.synced_folder ".", "/vagrant", type: "nfs"
if SYNC_TYPE == 'rsync' end
config.vm.synced_folder ".", "/vagrant", rsync: "nfs", if SYNC_TYPE == 'rsync'
config.vm.synced_folder ".", "/vagrant", rsync: "nfs",
rsync__args: ["--verbose", "--archive", "--delete", "-z"] rsync__args: ["--verbose", "--archive", "--delete", "-z"]
end
end end
end end
end end
end end
def boot_order(virt_config, order)
# Boot order is specified with special flag:
# --boot<1-4> none|floppy|dvd|disk|net
4.times do |idx|
device = order[idx] || 'none'
virt_config.customize ['modifyvm', :id, "--boot#{idx + 1}", device]
end
end

View File

@ -0,0 +1,13 @@
# Specify interface for dhcp server
interface={{dhcp_interface}}
bind-interfaces
# Specify IP addresses range
dhcp-range={{dhcp_range_start}},{{dhcp_range_end}},12h
# Net boot file name
dhcp-boot=tag:!nopxe,pxelinux.0
# Configure tftp
enable-tftp
tftp-root={{tftp_root}}

View File

@ -0,0 +1,8 @@
server {
listen 8000;
root /var/lib/tftp;
location / {
autoindex on;
}
}

View File

@ -0,0 +1,11 @@
default vesamenu.c32
menu title Live CD Choices
prompt 0
timeout 3
menu autoboot
label ubuntu
menu label Ubuntu
kernel /ubuntu/linux
append initrd=/ubuntu/initramfs.img verbose fetch=http://{{http_ip}}:{{http_port}}/ubuntu/root.squashfs ip=dhcp boot=live
iappend 2

View File

@ -0,0 +1,50 @@
---
- name: Setup dhcp server with bootstrap image
hosts: all
sudo: yes
vars:
tftp_root: /var/lib/tftp
dhcp_range_start: 10.0.0.42
dhcp_range_end: 10.0.0.53
dhcp_interface: eth1
pxe_netboot_image: http://archive.ubuntu.com/ubuntu/dists/trusty-updates/main/installer-amd64/current/images/netboot/pxelinux.0
pxe_netboot_menu: http://archive.ubuntu.com/ubuntu/dists/trusty-updates/main/installer-amd64/current/images/netboot/ubuntu-installer/amd64/boot-screens/vesamenu.c32
insecure_pub_key: https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub
insecure_pub_key_path: /tmp/ssh_insecure.pub
image_builder_path: /tmp/image_builder
http_ip: 10.0.0.2
http_port: 8000
tasks:
# Istall and configure dnsmasq
- apt: name=dnsmasq state=present
- file: path={{tftp_root}} state=directory
- template: src=files/dnsmasq_pxe.conf dest=/etc/dnsmasq.d/pxe.conf
- service: name=dnsmasq state=restarted
- file: path="{{tftp_root}}/pxelinux.cfg" state=directory
- template: src=files/pxelinux.cfg dest="{{tftp_root}}/pxelinux.cfg/default"
# Prepare pxe configs and download pxe image
- get_url: url={{pxe_netboot_image}} dest="{{tftp_root}}/pxelinux.0"
- get_url: url={{pxe_netboot_menu}} dest="{{tftp_root}}/vesamenu.c32"
# Build image
- get_url: url={{insecure_pub_key}} dest={{insecure_pub_key_path}}
- apt: name=debootstrap state=present
- file: path={{tftp_root}}/ubuntu state=directory
- git: repo=https://github.com/rustyrobot/fuel-bootstrap-image-builder dest={{image_builder_path}}
- shell: "{{image_builder_path}}/bin/fuel-bootstrap-image 2>&1 | tee /tmp/image_build.log"
environment:
BOOTSTRAP_SSH_KEYS: "{{insecure_pub_key_path}}"
DESTDIR: "{{tftp_root}}/ubuntu"
- file: path="{{tftp_root}}/ubuntu/{{item}}" mode=0644 state=file
with_items:
- initramfs.img
- linux
- root.squashfs
# Configure http server to load root
- apt: name=nginx state=present
- template: src=files/nginx.cfg dest=/etc/nginx/conf.d/pxe_image.conf
- service: name=nginx state=restarted

View File

@ -0,0 +1,61 @@
# Noop Vagrant plugins are used in case if Vagrant does not
# have an access to VMs (e.g. there is no information about ip),
# so it just runs VMs and does not try to perform additional
# actions using SSH.
class NoopCommunicator < Vagrant.plugin("2", :communicator)
def ready?
true
end
def wait_for_ready(timeout)
true
end
end
class NoopGuest < Vagrant.plugin("2", :guest)
def self.change_host_name(*args)
true
end
def self.configure_networks(*args)
true
end
def self.mount_virtualbox_shared_folder(*args)
true
end
end
class NoopCommunicatorPlugin < Vagrant.plugin("2")
name 'Noop communicator/guest'
description 'Noop communicator/guest'
communicator('noop') do
NoopCommunicator
end
guest 'noop_guest' do
NoopGuest
end
guest_capability 'noop_guest', 'change_host_name' do
NoopGuest
end
guest_capability 'noop_guest', 'configure_networks' do
NoopGuest
end
guest_capability 'noop_guest', 'mount_virtualbox_shared_folder' do
NoopGuest
end
end

View File

@ -17,3 +17,11 @@ slaves_cpus: 1
# Uncomment following option to change it. # Uncomment following option to change it.
# Possible options are: rsync, nfs # Possible options are: rsync, nfs
# sync_type: nfs # sync_type: nfs
# Use vagrant image in order to perform provisioning
preprovisioned: true
# Use pxe bootstrap in order to bootstrap nodes
# it should be used in order to provision nodes
# by solar
# preprovisioned: false