113 lines
5.2 KiB
YAML
Executable File
113 lines
5.2 KiB
YAML
Executable File
#!/usr/bin/env ansible-playbook --forks 50
|
|
---
|
|
# Distribute/prestage Glance image out to many compute nodes at once using BitTorrent
|
|
#
|
|
# Author: Kris Lindgren <klindgren@godaddy.com>
|
|
#
|
|
# Sets up a BitTorrent swarm, seeded by the machine running Glance, to distribute a Glance image out to any number
|
|
# of nova-compute nodes very quickly. So when we roll new gold images each month, we can use this to
|
|
# "push" them out to all compute nodes, and avoid the first provision penalty of waiting for the image
|
|
# to transfer the first time.
|
|
#
|
|
# Caveats:
|
|
# * Only works when the Glance backend is on a traditional (local or network-based) filesystem. Almost
|
|
# certainly this does not work, and may not even make sense, for Swift-backed Glance.
|
|
# * Firewalls or other traffic filters need to allow the BitTorrent ports through, and among, the Glance
|
|
# server and all compute nodes.
|
|
# * Assumes Glance images are stored at `/var/lib/glance/images` on the Glance server.
|
|
# * There are some situations where this cannot be run multiple times, if the tracker or othe BitTorrent
|
|
# processes are still running. So use caution, and YMMV.
|
|
# * This is done completely outside the scope of Glance and Nova. There is no Keystone authentication or
|
|
# access controls. You must have ssh and sudo access to all machines involved for this to work.
|
|
#
|
|
# This playbook requires the following variables:
|
|
# image_uuid - this can be gotten from the output of either nova image-list or glance image-list for the image you want to prestage
|
|
# image_sha1 - this can be gotten by running: echo -n "<image_uuid" | sha1sum | awk '{print $1'} on any linux box
|
|
# image_md5 - this can be gotten by running: md5sum /var/lib/glance/images/<image_uuid> | awk '{print $1}' on the glance server
|
|
# tracker_host - this is the host that runs the tracker (also this is the same host in the first and second play)
|
|
# hosts_to_update - this is the host group to place the image onto typically *-compute
|
|
|
|
# To run without changing the plabook with differnt uuids run ansible-plabook with the following:
|
|
# ansible-playbook template-prestage.yaml -k -K --extra-vars "image_uuid=41009dbd-52f5-4972-b65f-c429b1d42f5f image_sha1=1b8cddc7825df74e19d0a621ce527a0272541c35 image_md5=41d45920d859a2d5bd4d1ed98adf7668 tracker_host=api01 hosts_to_update=compute"
|
|
|
|
- hosts: '{{ tracker_host }}'
|
|
sudo: yes
|
|
vars:
|
|
image_uuid: '{{ image_uuid }}'
|
|
tracker_host: '{{ tracker_host }}'
|
|
tasks:
|
|
- name: install ctorrent client
|
|
yum: name=ctorrent state=present
|
|
|
|
- name: install opentracker-ipv4
|
|
yum: name=opentracker-ipv4 state=present
|
|
|
|
- name: make sane
|
|
shell: "killall -9 opentracker-ipv4 | true; killall -9 ctorrent | true;"
|
|
|
|
- name: Start Tracker
|
|
command: "{{item}}"
|
|
with_items:
|
|
- /usr/bin/opentracker-ipv4 -m -p 6969 -P 6969 -d /var/opentracker
|
|
|
|
- name: Create bittorrent file
|
|
command: "{{item}}"
|
|
with_items:
|
|
- mkdir -p /var/www/html/torrent
|
|
- rm -rf /var/www/html/torrent/{{ image_uuid }}.torrent
|
|
- /usr/bin/ctorrent -t -s /var/www/html/torrent/{{ image_uuid }}.torrent -u http://{{ tracker_host }}:6969/announce -c Testfile /var/lib/glance/images/{{ image_uuid }}
|
|
|
|
- name: Seed Bittorrent file
|
|
command: /usr/bin/ctorrent -d -U 50000 -s /var/lib/glance/images/{{ image_uuid }} /var/www/html/torrent/{{ image_uuid }}.torrent
|
|
|
|
- hosts: '{{hosts_to_update}}'
|
|
sudo: yes
|
|
vars:
|
|
image_uuid: '{{ image_uuid }}'
|
|
image_sha1: '{{ image_sha1 }}'
|
|
image_md5: '{{ image_md5 }}'
|
|
tracker_host: '{{ tracker_host }}'
|
|
tasks:
|
|
- name: install ctorrent client
|
|
yum: name=ctorrent state=present
|
|
|
|
- name: Check if image exits
|
|
stat: path=/var/lib/nova/instances/_base/{{ image_sha1 }}
|
|
register: image
|
|
|
|
- name: make sane
|
|
shell: "killall -9 ctorrent | true; iptables -D INPUT -p tcp --dport 2704:2706 -j ACCEPT | true"
|
|
when: image.stat.exists == False
|
|
|
|
- name: Download Torrent File and run torrent
|
|
command: "{{item}}"
|
|
with_items:
|
|
- /sbin/iptables -I INPUT -p tcp --dport 2704:2706 -j ACCEPT
|
|
- /usr/bin/wget http://{{ tracker_host }}/torrent/{{ image_uuid }}.torrent
|
|
- /usr/bin/ctorrent -e 0 -m 10 -U 30000 -D 80000 -p 2706 -s /var/lib/elsprecachedir/{{ image_uuid }} {{ image_uuid }}.torrent
|
|
when: image.stat.exists == False
|
|
|
|
- name: insure md5sum matches
|
|
shell: "md5sum /var/lib/elsprecachedir/{{ image_uuid }} | grep {{ image_md5 }}"
|
|
when: image.stat.exists == False
|
|
|
|
- name: Convert image to raw file
|
|
command: "{{item}}"
|
|
with_items:
|
|
- /usr/bin/qemu-img convert -f qcow2 -O raw /var/lib/elsprecachedir/{{ image_uuid }} /var/lib/nova/instances/_base/{{ image_sha1 }}
|
|
- /bin/chown nova:qemu /var/lib/nova/instances/_base/{{ image_sha1 }}
|
|
- /bin/chmod 644 /var/lib/nova/instances/_base/{{ image_sha1 }}
|
|
when: image.stat.exists == False
|
|
|
|
- name: Cleanup
|
|
shell: "/sbin/iptables -D INPUT -p tcp --dport 2704:2706 -j ACCEPT | true; rm -rf {{ image_uuid }}*; rm -rf /var/lib/elsprecachedir/{{ image_uuid }}; killall -9 ctorrent | true"
|
|
when: image.stat.exists == False
|
|
|
|
- hosts: '{{ tracker_host }}'
|
|
sudo: yes
|
|
vars:
|
|
image_uuid: '{{ image_uuid }}'
|
|
tasks:
|
|
- name: Kill tracker and ctorrent and remove torrent file
|
|
shell: "killall -9 ctorrent | true ; killall -9 opentracker-ipv4 | true; rm -rf /var/www/html/torrent/{{ image_uuid }}"
|