Addition of dynamic configuration drives

Adding a modified role, and base testing playbook updates, to allow
for dynamic generation of configuration drives utilizing the dynamic
inventory.

Change-Id: Ibe4a5761da828a39066d99c75b724af5ff670239
This commit is contained in:
Julia Kreger 2015-06-04 19:06:32 -04:00
parent 894cddb8b7
commit 0b82a03408
11 changed files with 355 additions and 1 deletions

View File

@ -0,0 +1,74 @@
bifrost-configdrives
====================
Creates configdrives for nodes being provisioned in Bifrost.
Requirements
------------
This playbook is intended to be executed prior to the deployments of nodes via the bifrost-setup-nodes role, as part of Bifrost. It creates a basic configuration drive containing network configuration and an SSH key permitting the user to login to the host.
Role Variables
--------------
This role, like the other deployment related bifrost playbooks are expected to be executed with the bifrost dynamic inventory or a compatible configuration data source.
Additional key variables are:
addressing_mode: If defined and set to a value of "dhcp", this role sets the primary interface to utilize DHCP.
ipv4_subnet_mask: This is the subnet mask(e.g. 255.255.255.0 or similar) that matches the static addressing which desires to be imprinted into the configuration drive.
ipv4_gateway: This is the IPv4 default router address within the IPv4 subnet being utilized for IP addresses for the nodes being deployed.
node_default_network_interface: This is the default network interface within the nodes to be deployed which the new IP configuration will be applied to. Note: This is likely to be deprecated and removed in the future as Bifrost will likely change methods utilized to include networking configuration into the configuration drive sufficiently that this should no longer be required.
ipv4_nameserver: Defines the IPv4 Nameserver to configure the node with initially in order to support name resolution.
ipv4_address: The IPv4 address of the node to be deployed, if applicable.
ssh_public_key_path: Defines the path to the file to be SSH public key to be inserted into the configuration drive.
ssh_public_key: If a user wishes to define an SSH public key as a string, this variable can be utilized which overrides ssh_public_key_path.
uuid: The UUID value for the node.
http_boot_folder: The folder where to save the configuration drive file to.
Customizing
-----------
The attempt with this playbook is to create a very simple and easily modifiable configuration drive to be loaded to the remote machine. This is done for each host that the role is run against.. If one wishes to insert additional files, this can be done by editing the tasks/main.yml file. As the drives are generated in a stepwise fashion, it is important to make note of and use the "{{ uuid }}" variable as that is utilized to delineate the file destinations between different configuration drives that may be in the process of being created.
Additional detail on the format of configuration drives can be found at http://docs.openstack.org/user-guide/content/enable_config_drive.html.
If one wishes to manually modify a configuration drive after the fact, the files are base64 encoded, gzip compressed, ISO9660 filesystems. Ironic will fail the deployment of the configuration drive if the file is not first found to be base64 encoded, and then gzip compressed. Alternatively, the configuration drive can be a vfat filesystem, although this carries with it some risks if the filesystem is always treated as a source of truth upon system boot.
One final note. The size of the configuration drives is limited to 64MB. This is not a limit of Bifrost, but a limit due to the code utilized to write the configuration drive out.
Dependencies
------------
This role is expected to be executed on a system that has had the ironic-install role executed upon it, however as the configuration drive creation step is fairly self contained, it can be executed as a separate step.
Example Playbook
----------------
- hosts: baremetal
connection: local
sudo: no
roles:
- role: bifrost-configdrives-dynamic
License
-------
Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
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 writing, 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.
Author Information
------------------
Ironic Developers

View File

@ -0,0 +1,2 @@
---
# defaults file for bifrost-configdrives-dynamic

View File

@ -0,0 +1,2 @@
---
# handlers file for bifrost-configdrives-dynamic

View File

@ -0,0 +1,116 @@
---
galaxy_info:
author: Ironic Developers
description: Creates a basic configdrive for Bifrost
company: OpenStack
license: Apache
min_ansible_version: 1.9
#
# Below are all platforms currently available. Just uncomment
# the ones that apply to your role. If you don't see your
# platform on this list, let us know and we'll get it added!
#
platforms:
#- name: EL
# versions:
# - all
# - 5
# - 6
# - 7
#- name: GenericUNIX
# versions:
# - all
# - any
#- name: Fedora
# versions:
# - all
# - 16
# - 17
# - 18
# - 19
# - 20
#- name: SmartOS
# versions:
# - all
# - any
#- name: opensuse
# versions:
# - all
# - 12.1
# - 12.2
# - 12.3
# - 13.1
# - 13.2
#- name: Amazon
# versions:
# - all
# - 2013.03
# - 2013.09
#- name: GenericBSD
# versions:
# - all
# - any
#- name: FreeBSD
# versions:
# - all
# - 8.0
# - 8.1
# - 8.2
# - 8.3
# - 8.4
# - 9.0
# - 9.1
# - 9.1
# - 9.2
#- name: Ubuntu
# versions:
# - all
# - lucid
# - maverick
# - natty
# - oneiric
# - precise
# - quantal
# - raring
# - saucy
- trusty
#- name: SLES
# versions:
# - all
# - 10SP3
# - 10SP4
# - 11
# - 11SP1
# - 11SP2
# - 11SP3
#- name: GenericLinux
# versions:
# - all
# - any
#- name: Debian
# versions:
# - all
# - etch
# - lenny
# - squeeze
# - wheezy
#
# Below are all categories currently available. Just as with
# the platforms above, uncomment those that apply to your role.
#
categories:
- cloud
- cloud:openstack
#- cloud:gce
#- cloud:rax
#- clustering
#- database
#- database:nosql
#- database:sql
#- development
#- monitoring
#- networking
#- packaging
#- system
#- web
dependencies: []

View File

@ -0,0 +1,47 @@
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# 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 writing, 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: "Identify ssh_public_key if ssh_public_key_path is defined"
include: ssh_public_key_path.yaml
when: ssh_public_key is undefined and ssh_public_key_path is defined
- name: "Name Make Temporary folder to build configdrive"
local_action: command mktemp -d
register: variable_configdrive_location
- name: "Make Metadata folder - /openstack/{{ metaata_version }}"
local_action: file state=directory name={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/{{ metadata_version }}/
- name: "Make Metadata folder - /openstack/latest"
local_action: file state=directory name={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/latest/
- name: "Place template in each openstack/{{ metadata_version }} folder"
local_action: template src=openstack_meta_data.json.j2 dest={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/{{ metadata_version }}/meta_data.json
- name: "Place template in each openstack/latest folder"
local_action: template src=openstack_meta_data.json.j2 dest={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/latest/meta_data.json
- name: "Place network info template in each openstack/latest folder"
local_action: template src=network_info.json.j2 dest={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/latest/network_info.json
when: addressing_mode is undefined and '"dhcp" not in addressing_mode'
- name: "Make Metadata folder - /openstack/latest"
local_action: file state=directory name={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/content/
- name: "Write network interface template"
local_action: template src=interfaces.j2 dest={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/content/0000
- name: "Make config drive files"
sudo: yes
local_action: command mkisofs -R -V config-2 -o {{http_boot_folder}}/configdrive-{{ uuid }}.iso {{ variable_configdrive_location.stdout }}/{{ uuid }}
- name: "Make config drive files base64 encoded and gzip compressed"
sudo: yes
local_action: shell gzip -c {{http_boot_folder}}/configdrive-{{ uuid }}.iso | base64 > {{http_boot_folder}}/configdrive-{{ uuid }}.iso.gz
- name: "Cleanup configdrive .iso files"
sudo: yes
local_action: file state=absent name={{http_boot_folder}}/configdrive-{{ uuid }}.iso
- name: "Cleanup configdrive temp folder"
sudo: yes
local_action: file state=absent force=yes name={{ variable_configdrive_location.stdout }}

View File

@ -0,0 +1,33 @@
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# 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 writing, 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: "Determine if OpenStack CI is missing an SSH key"
stat: path={{ssh_public_key_path}}
register: test_ssh_public_key_path
when: ci_testing_zuul is defined
- name: "Create an SSH key for Jenkins user if operating in OpenStack CI"
shell: ssh-keygen -f ~/.ssh/id_rsa -N ""
when: ci_testing_zuul is defined and test_ssh_public_key_path.stat.exists == false
- name: "Create an empty ssh known_hosts file for Jenkins user if operating in OpenStack CI"
shell: touch ~/.ssh/known_hosts && chmod 600 ~/.ssh/known_hosts
when: ci_testing_zuul is defined and test_ssh_public_key_path.stat.exists == false
- name: "Defined ssh_public_key_path - Check to see if there is a file where the ssh_public_key_path is defined"
local_action: stat path={{ ssh_public_key_path }}
register: test_ssh_public_key_path
when: ssh_public_key_path is defined
- name: "Defined ssh_public_key_path - Error if ssh_public_key_path is not valid"
local_action: fail msg="ssh_public_key_path is not valid."
when: test_ssh_public_key_path.stat.exists == false
- name: "Defined ssh_public_key_path - Read ssh public key in"
set_fact: ssh_public_key="{{ lookup('file', ssh_public_key_path ) }}"

View File

@ -0,0 +1,16 @@
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
auto {{ node_default_network_interface }}
iface {{ node_default_network_interface }} inet static
{% if addressing_mode is defined and "dhcp" in addressing_mode %}
iface {{ node_default_network_interface }} inet dhcp
{% else %}
iface {{ node_default_network_interface }} inet static
address {{ ipv4_address }}
netmask {{ ipv4_subnet_mask }}
gateway {{ ipv4_gateway }}
dns-nameservers {{ ipv4_nameserver }}
{% endif %}

View File

@ -0,0 +1,41 @@
{
"links": [
{
"id": "{{node_default_network_interface}}",
"type": "phy",
{#
NOTE(TheJulia): I cannot determine a better way of doing this
with the information that we have available to us in nics.
#}
{% for nic in nics %}
{%- if loop.first %} "ethernet_mac_address": "{{ nic.mac }}",{% endif %}
{% endfor %}
"mtu":1500
}
],
"networks": [
{
"id": "publicnet-ipv4",
"type": "ipv4",
"link": "{{ node_default_network_interface }}",
"ip_address": "{{ ipv4_address }}",
"netmask": "{{ipv4_subnet_mask}}",
"dns_nameservers": [
"{{ipv4_nameserver}}"
],
"routes": [
{
"network": "0.0.0.0",
"netmask": "0.0.0.0",
"gateway": "{{ipv4_gateway}}"
}
]
}
],
"services": [
{
"type": "dns",
"address": "{{ipv4_nameserver}}"
}
]
}

View File

@ -0,0 +1,16 @@
{
"availability_zone": "",
"files": [
{
"content_path": "/content/0000",
"path": "/etc/network/interfaces"
}
],
"hostname": "{{ name }}",
"name": "{{ name }}",
"meta": {},
"public_keys": {
"mykey": "{{ ssh_public_key }}"
},
"uuid": "{{ uuid }}"
}

View File

@ -0,0 +1,2 @@
---
metadata_version: "2012-08-10"

View File

@ -42,13 +42,18 @@
sudo: yes
roles:
- role: bifrost-validate-host-for-deploy
- hosts: baremetal
name: "Creat configuration drives."
sudo: no
connection: local
roles:
- role: bifrost-configdrives-dynamic
- hosts: localhost
connection: local
name: "Executes install, enrollment, and testing in one playbook"
sudo: no
gather_facts: yes
roles:
- role: bifrost-configdrives
- role: bifrost-setup-nodes
- role: bifrost-prepare-for-test
# The testvm Host group is added by bifrost-prepare-for-test based