bd82c6a3e5
On occasion, a set of saved images may not have a gvwstate.dat file. Given that the MNAIO tooling is for test purposes only, we can take the risk of just making one up in order to ensure that the cluster starts on boot. DO NOT DO THIS IN PRODUCTION! Change-Id: I1b055ef0d02d77afe03d1a90baa2e6890e986c32
437 lines
13 KiB
YAML
437 lines
13 KiB
YAML
---
|
|
# Copyright 2018, Rackspace US, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in witing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
- name: Gather Facts for vm_hosts
|
|
hosts: vm_hosts
|
|
gather_facts: yes
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Get info about existing virt storage pools
|
|
virt_pool:
|
|
command: info
|
|
register: _virt_pools
|
|
|
|
- name: Set virt_pools host fact
|
|
set_fact:
|
|
virt_pools: "{{ _virt_pools }}"
|
|
|
|
- name: Get info about existing VM's
|
|
virt:
|
|
command: list_vms
|
|
register: _virt_list
|
|
|
|
- name: Stop all running VM's
|
|
virt:
|
|
name: "{{ item }}"
|
|
command: destroy
|
|
failed_when: false
|
|
with_items: "{{ _virt_list.list_vms }}"
|
|
|
|
- name: Delete any disk images related to running VM's
|
|
file:
|
|
path: "{{ _virt_pools.pools.default.path | default('/data/images') }}/{{ item }}.img"
|
|
state: absent
|
|
with_items: "{{ _virt_list.list_vms }}"
|
|
|
|
- name: Undefine all running VM's
|
|
virt:
|
|
name: "{{ item }}"
|
|
command: undefine
|
|
failed_when: false
|
|
with_items: "{{ _virt_list.list_vms }}"
|
|
|
|
- name: Find existing base image files
|
|
find:
|
|
paths: "{{ _virt_pools.pools.default.path | default('/data/images') }}"
|
|
patterns: '*-base.img'
|
|
register: _base_images
|
|
|
|
- name: Enable/disable vm_use_snapshot based on whether there are base image files
|
|
set_fact:
|
|
vm_use_snapshot: "{{ _base_images['matched'] > 0 }}"
|
|
|
|
- name: Clean up base image files if they are not being used
|
|
file:
|
|
path: "{{ item.path }}"
|
|
state: absent
|
|
with_items: "{{ _base_images.files }}"
|
|
when:
|
|
- not (vm_use_snapshot | bool)
|
|
|
|
|
|
- name: Prepare VM storage
|
|
hosts: pxe_servers
|
|
gather_facts: no
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Create VM Disk Image
|
|
command: >-
|
|
qemu-img create
|
|
-f qcow2
|
|
{% if hostvars[item]['vm_use_snapshot'] | bool %}
|
|
-b {{ hostvars[item]['virt_pools'].pools.default.path | default('/data/images') }}/{{ server_hostname }}-base.img
|
|
{% endif %}
|
|
{{ hostvars[item]['virt_pools'].pools.default.path | default('/data/images') }}/{{ server_hostname }}.img
|
|
{{ default_vm_storage }}m
|
|
when:
|
|
- server_vm | default(false) | bool
|
|
delegate_to: "{{ item }}"
|
|
with_items: "{{ groups['vm_hosts'] }}"
|
|
|
|
|
|
- name: Prepare file-based disk images
|
|
hosts: vm_hosts
|
|
gather_facts: yes
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
# Note (odyssey4me):
|
|
# This will only work on a host which has
|
|
# libguestfs >= 1.35.2 and >= 1.34.1
|
|
# Ubuntu bionic works, but xenial does not (even with UCA).
|
|
# ref: https://bugs.launchpad.net/ubuntu/+source/libguestfs/+bug/1615337.
|
|
- name: Prepare file-based disk images
|
|
when:
|
|
- vm_use_snapshot | bool
|
|
block:
|
|
- name: Inject the host ssh key into the VM disk image
|
|
command: >-
|
|
virt-sysprep
|
|
--enable customize
|
|
--ssh-inject root:file:/root/.ssh/id_rsa.pub
|
|
--add {{ virt_pools.pools.default.path | default('/data/images') }}/{{ hostvars[item]['server_hostname'] }}.img
|
|
when:
|
|
- hostvars[item]['server_vm'] | default(false) | bool
|
|
with_items: "{{ groups['pxe_servers'] }}"
|
|
|
|
- name: Copy over prepare-image-galera.sh
|
|
copy:
|
|
src: kvm/prepare-image-galera.sh
|
|
dest: /opt/prepare-image-galera.sh
|
|
mode: "0755"
|
|
|
|
- name: Prepare the galera containers for startup
|
|
command: /opt/prepare-image-galera.sh
|
|
register: _galera_prepare
|
|
|
|
# guestfish does not always give a return code which indicates
|
|
# failure, so we look for our final stdout output as an indicator
|
|
- name: Fail if the preparation script did not complete
|
|
fail:
|
|
msg: "The galera container preparation failed."
|
|
when:
|
|
- "'Image preparation completed.' not in _galera_prepare.stdout_lines"
|
|
|
|
|
|
- name: Prepare VM's
|
|
hosts: pxe_servers
|
|
gather_facts: no
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Define the VM
|
|
virt:
|
|
name: "{{ server_hostname }}"
|
|
command: define
|
|
xml: >-
|
|
{%- if hostvars[item]['vm_use_snapshot'] | bool %}
|
|
{{ lookup('file', hostvars[item]['virt_pools'].pools.default.path | default('/data/images') ~ '/' ~ server_hostname ~ '.xml') }}
|
|
{%- else %}
|
|
{{ lookup('template', 'kvm/kvm-vm.xml.j2') }}
|
|
{%- endif %}
|
|
failed_when: false
|
|
when:
|
|
- server_vm | default(false) | bool
|
|
delegate_to: "{{ item }}"
|
|
with_items: "{{ groups['vm_hosts'] }}"
|
|
|
|
- name: Get the VM xml
|
|
virt:
|
|
command: get_xml
|
|
name: "{{ server_hostname }}"
|
|
register: vm_xml
|
|
when:
|
|
- server_vm | default(false) | bool
|
|
delegate_to: "{{ item }}"
|
|
with_items: "{{ groups['vm_hosts'] }}"
|
|
|
|
- name: Write the VM xml
|
|
copy:
|
|
content: "{{ item.1.get_xml }}"
|
|
dest: "/etc/libvirt/qemu/{{ item.1.item }}.xml"
|
|
when:
|
|
- server_vm | default(false) | bool
|
|
delegate_to: "{{ item.0 }}"
|
|
with_nested:
|
|
- "{{ groups['vm_hosts'] }}"
|
|
- "{{ vm_xml.results }}"
|
|
|
|
|
|
- name: Start VM's
|
|
hosts: vm_hosts
|
|
gather_facts: "{{ gather_facts | default(true) }}"
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Gather variables for each operating system
|
|
include_vars: "{{ item }}"
|
|
with_first_found:
|
|
- "{{ playbook_dir }}/vars/{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml"
|
|
- "{{ playbook_dir }}/vars/{{ ansible_distribution | lower }}-{{ ansible_distribution_major_version | lower }}.yml"
|
|
- "{{ playbook_dir }}/vars/{{ ansible_os_family | lower }}-{{ ansible_distribution_major_version | lower }}.yml"
|
|
- "{{ playbook_dir }}/vars/{{ ansible_distribution | lower }}.yml"
|
|
- "{{ playbook_dir }}/vars/{{ ansible_os_family | lower }}.yml"
|
|
tags:
|
|
- always
|
|
|
|
- name: Start VM
|
|
virt:
|
|
name: "{{ hostvars[item]['server_hostname'] }}"
|
|
command: start
|
|
state: running
|
|
failed_when: false
|
|
when:
|
|
- hostvars[item]['server_vm'] | default(false) | bool
|
|
with_items: "{{ groups['pxe_servers'] }}"
|
|
|
|
- name: Add VM to /etc/hosts file
|
|
lineinfile:
|
|
path: "/etc/hosts"
|
|
line: "{{ hostvars[item]['ansible_host'] }} {{ hostvars[item]['server_hostname'] }}"
|
|
when:
|
|
- hostvars[item]['server_vm'] | default(false) | bool
|
|
with_items: "{{ groups['pxe_servers'] }}"
|
|
|
|
|
|
- name: Check VM Connectivity
|
|
import_playbook: vm-status.yml
|
|
|
|
|
|
- name: Add SSH keys to VM's and containers
|
|
hosts: vm_servers:all_containers
|
|
gather_facts: false
|
|
any_errors_fatal: true
|
|
tasks:
|
|
- name: Copy Host SSH Keys
|
|
copy:
|
|
src: "{{ item.src }}"
|
|
dest: "{{ item.dest }}"
|
|
mode: "0600"
|
|
with_items:
|
|
- src: "{{ lookup('env', 'HOME') }}/.ssh/id_rsa"
|
|
dest: /root/.ssh/id_rsa
|
|
- src: "{{ lookup('env', 'HOME') }}/.ssh/id_rsa.pub"
|
|
dest: /root/.ssh/id_rsa.pub
|
|
|
|
- name: Add authorized key
|
|
authorized_key:
|
|
user: root
|
|
state: present
|
|
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
|
|
|
|
|
|
# In vm-post-install-script.sh.j2 we chattr +i the interfaces file to prevent
|
|
# the preseed system from overwriting the file after we've modified it. The
|
|
# task below simply removes the immutable attribute.
|
|
- name: Remove immutable attr from /etc/network/interfaces
|
|
hosts: vm_servers
|
|
gather_facts: true
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Remove immutable attr from /etc/network/interfaces
|
|
file:
|
|
path: /etc/network/interfaces
|
|
attr: ""
|
|
when:
|
|
- ansible_distribution | lower == "ubuntu"
|
|
- ansible_distribution_release | lower == "trusty"
|
|
|
|
|
|
- name: Set MaxSessions and MaxStartups to reduce connection failures
|
|
hosts: vm_servers
|
|
gather_facts: "{{ gather_facts | default(true) }}"
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Gather variables for each operating system
|
|
include_vars: "{{ item }}"
|
|
with_first_found:
|
|
- "{{ playbook_dir }}/vars/{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml"
|
|
- "{{ playbook_dir }}/vars/{{ ansible_distribution | lower }}-{{ ansible_distribution_major_version | lower }}.yml"
|
|
- "{{ playbook_dir }}/vars/{{ ansible_os_family | lower }}-{{ ansible_distribution_major_version | lower }}.yml"
|
|
- "{{ playbook_dir }}/vars/{{ ansible_distribution | lower }}.yml"
|
|
- "{{ playbook_dir }}/vars/{{ ansible_os_family | lower }}.yml"
|
|
tags:
|
|
- always
|
|
|
|
- name: Set MaxStartups
|
|
lineinfile:
|
|
path: /etc/ssh/sshd_config
|
|
line: MaxStartups 100
|
|
state: present
|
|
regexp: '^MaxStartups.*$'
|
|
notify:
|
|
- restart sshd
|
|
|
|
- name: Set MaxSessions
|
|
lineinfile:
|
|
path: /etc/ssh/sshd_config
|
|
line: MaxSessions 100
|
|
state: present
|
|
regexp: '^MaxSessions.*$'
|
|
notify:
|
|
- restart sshd
|
|
|
|
handlers:
|
|
- name: restart sshd
|
|
service:
|
|
name: "{{ ssh_service_name }}"
|
|
state: restarted
|
|
|
|
|
|
- name: Make space for swift/cinder/ceph volumes
|
|
hosts: cinder_hosts:swift_hosts:ceph_hosts:&vm_servers
|
|
gather_facts: "{{ gather_facts | default(true) }}"
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Unmount unnecessary mounts
|
|
mount:
|
|
name: "{{ item }}"
|
|
state: absent
|
|
with_items:
|
|
- "/var/lib/lxc"
|
|
- "/var/lib/machines"
|
|
register: _remove_mounts
|
|
|
|
- name: Remove unnecessary logical volumes
|
|
lvol:
|
|
vg: vmvg00
|
|
lv: "{{ item }}"
|
|
force: true
|
|
state: absent
|
|
with_items:
|
|
- "lxc00"
|
|
- "machines00"
|
|
register: _remove_lvs
|
|
|
|
- name: Reload systemd to remove generated unit files for mount
|
|
systemd:
|
|
daemon_reload: yes
|
|
when:
|
|
- "ansible_service_mgr == 'systemd'"
|
|
- "(_remove_mounts is changed) or (_remove_lvs is changed)"
|
|
|
|
- name: Set fact to indicate that the volumes changed (later used to force formatting)
|
|
set_fact:
|
|
_force_format_disks: "{{ (_remove_mounts is changed) or (_remove_lvs is changed) }}"
|
|
|
|
- name: Setup cinder host volume
|
|
hosts: cinder_hosts:&vm_servers
|
|
gather_facts: "{{ gather_facts | default(true) }}"
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Create cinder-volumes LV
|
|
lvol:
|
|
vg: vmvg00
|
|
lv: cinder-volumes00
|
|
size: "100%FREE"
|
|
shrink: false
|
|
|
|
- name: Create data cinder-volumes VG
|
|
lvg:
|
|
vg: cinder-volumes
|
|
pvs: "/dev/vmvg00/cinder-volumes00"
|
|
|
|
|
|
- name: Setup swift host volume
|
|
hosts: swift_hosts:&vm_servers
|
|
gather_facts: "{{ gather_facts | default(true) }}"
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Create swift disk LV's
|
|
lvol:
|
|
vg: vmvg00
|
|
lv: "{{ item }}"
|
|
size: 4G
|
|
with_items:
|
|
- disk1
|
|
- disk2
|
|
- disk3
|
|
|
|
- name: Format swift drives
|
|
filesystem:
|
|
fstype: xfs
|
|
dev: "/dev/vmvg00/{{ item }}"
|
|
force: "{{ _force_format_disks | default(False) }}"
|
|
with_items:
|
|
- disk1
|
|
- disk2
|
|
- disk3
|
|
|
|
- name: Mount swift drives
|
|
mount:
|
|
name: "/srv/{{ item }}"
|
|
src: "/dev/mapper/vmvg00-{{ item }}"
|
|
fstype: xfs
|
|
state: mounted
|
|
opts: defaults,discard
|
|
with_items:
|
|
- disk1
|
|
- disk2
|
|
- disk3
|
|
|
|
- name: Setup ceph OSD volumes
|
|
hosts: ceph_hosts:&vm_servers
|
|
gather_facts: "{{ gather_facts | default(true) }}"
|
|
environment: "{{ deployment_environment_variables | default({}) }}"
|
|
tags:
|
|
- deploy-vms
|
|
tasks:
|
|
- name: Create ceph OSD journal LV's
|
|
lvol:
|
|
vg: vmvg00
|
|
lv: "{{ item }}"
|
|
size: "{{ ceph_journal_size }}"
|
|
with_items:
|
|
- journal1
|
|
- journal2
|
|
- journal3
|
|
|
|
- name: Create ceph OSD disk LV's
|
|
lvol:
|
|
vg: vmvg00
|
|
lv: "{{ item }}"
|
|
size: "{{ ceph_osds_size }}"
|
|
with_items:
|
|
- data1
|
|
- data2
|
|
- data3
|