From edd5b67afc9fea17bf3d8006d2a2c83cb5ab700d Mon Sep 17 00:00:00 2001 From: Julia Kreger Date: Sat, 11 Jul 2015 13:22:04 -0400 Subject: [PATCH] Switch to simple-init for network configuration Bifrost defining and attempting to bake in configuration files into configuration drives to allow initial configuration of connectivity is a crazy idea. Since the Openstack-infra folks have glean and simple-init, we will utilize their tooling to provide greater flexibility across operating systems. Additionally, the ability to write out a simple debian style interfaces config file has been retained, however off by default as it is necessary for cirros testing. In addition to this, the ability for inventory based data to override the contents of the network_info.json file. Change-Id: Id85b18277b4d78acf418f63f046e39e889590719 Closes-Bug: 1463191 --- README.rst | 35 +++++++---- .../bifrost-configdrives-dynamic/README.md | 10 ++++ .../defaults/main.yml | 6 +- .../tasks/main.yml | 3 +- .../templates/network_info.json.j2 | 60 +++++++++++++++---- .../templates/openstack_meta_data.json.j2 | 4 ++ .../defaults/main.yml | 1 - .../bifrost-create-dib-image/tasks/main.yml | 2 +- scripts/test-bifrost.sh | 2 +- 9 files changed, 96 insertions(+), 27 deletions(-) diff --git a/README.rst b/README.rst index 906062577..992106335 100644 --- a/README.rst +++ b/README.rst @@ -90,7 +90,6 @@ The install process builds or modifies a disk image to deploy. The following two create_image_via_dib: true transform_boot_image: false - Proxy:: if running behind the proxy. export environment variables http_proxy and https_proxy @@ -115,6 +114,8 @@ in a stand-alone fashion. from Nginx. * standard ipmitool is used. TODO: make optional support for other hardware drivers +* By default, installation will build an Ubuntu based image for deployment + to nodes. This image can be easily customized if so desired. The re-execution of the playbook will cause states to be re-asserted. If not already present, a number of software packages including MySQL and RabbitMQ @@ -261,7 +262,6 @@ The CSV file has the following columns: Example definition:: - 00:11:22:33:44:55,root,undefined,192.168.122.1,1,8192,512,NA,NA,aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee,hostname_100,192.168.2.100,,,,agent_ipmitool This file format is fairly flexible and can be easily modified @@ -356,14 +356,27 @@ will use this key to connect to the host machine and run virsh commands. #. Run the enrollment step, as documented above, using the CSV file you created in the previous step. #. Run the deployment step, as documented above. -Network/SSH key configuration for RedHat/Centos -=============================================== +Deployment and configuration of Operating Systems +================================================= -Bifrost places a file in the configuration drive named network_info.json that -can be read/parsed by the `glean ` -utility. This has greater compatibility for network configuration, however -any physical servers connected should be connected to switches configured such -that the network ports immediately go into a forwarding state. +By default, Bifrost deploys a configuration drive which includes the user SSH +public key, hostname, and the network configuration in the form of +network_info.json that can be read/parsed by the +`glean ` utility. This allows for +the deployment of Ubuntu, CentOS, Fedora "tenants" on baremetal. This file +format is not yet supported by Cloud-Init, however it is on track for +inclusion in cloud-init 2.0. -In order to activate use of glean, you will want to utilize disk images -built with the diskimage-builder ``simple-init`` element. +By default, Bifrost utilizes a utility called simple-init which leverages +the previously noted glean utility to apply network configuration. This +means that by default, root file systems may not be automatically expanded +to consume the entire disk, which may, or may not be desirable depending +upon operational needs. This is dependent upon what base OS image you +utilize, and if the support is included in that image or not. At present, +the standard ubuntu cloud image includes cloud-init which will grow the +root partition, however the minimal image does not include the image, and +thus will not grow the root partition. + +Due to the nature of the design, it would be relatively easy for a user to +import automatic growth or reconfiguration steps either in the image to be +deployed, or in post-deployment steps via custom Ansible playbooks. diff --git a/playbooks/roles/bifrost-configdrives-dynamic/README.md b/playbooks/roles/bifrost-configdrives-dynamic/README.md index 3e8b2697a..59c7add00 100644 --- a/playbooks/roles/bifrost-configdrives-dynamic/README.md +++ b/playbooks/roles/bifrost-configdrives-dynamic/README.md @@ -18,6 +18,8 @@ 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. +ipv4_interface_mac: Optional: The MAC address of the network interface to + assign the IPv4 address to. 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. @@ -25,6 +27,14 @@ ssh_public_key_path: Defines the path to the file to be SSH public key to be ins 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. +write_interfaces_file: Legacy option to write an debian style network + interfaces configuration file. This is required for + deployment where simple-init cannot be used, in + particular when using Cirros. +node_network_info: Optional: If defined, the contents are written out to the + network_info.json file, effectively allowing a user to + override the network configuration contents based on + the inventory data. Customizing ----------- diff --git a/playbooks/roles/bifrost-configdrives-dynamic/defaults/main.yml b/playbooks/roles/bifrost-configdrives-dynamic/defaults/main.yml index 242f9d65b..435f2a763 100644 --- a/playbooks/roles/bifrost-configdrives-dynamic/defaults/main.yml +++ b/playbooks/roles/bifrost-configdrives-dynamic/defaults/main.yml @@ -1,2 +1,6 @@ --- -# defaults file for bifrost-configdrives-dynamic +# write_interfaces_file is intended for utilizing base logic to write +# a debian style interfaces file into the configuration drive file +# such that cirros will receive basic network configuration when +# performing basic testing. +write_interfaces_file: false diff --git a/playbooks/roles/bifrost-configdrives-dynamic/tasks/main.yml b/playbooks/roles/bifrost-configdrives-dynamic/tasks/main.yml index d76a56077..7ff3aaedf 100644 --- a/playbooks/roles/bifrost-configdrives-dynamic/tasks/main.yml +++ b/playbooks/roles/bifrost-configdrives-dynamic/tasks/main.yml @@ -31,8 +31,9 @@ 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" +- name: "Write network Debian style interface template" local_action: template src=interfaces.j2 dest={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/content/0000 + when: write_interfaces_file | bool - 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 }} diff --git a/playbooks/roles/bifrost-configdrives-dynamic/templates/network_info.json.j2 b/playbooks/roles/bifrost-configdrives-dynamic/templates/network_info.json.j2 index 6922ff47f..9b40e2f13 100644 --- a/playbooks/roles/bifrost-configdrives-dynamic/templates/network_info.json.j2 +++ b/playbooks/roles/bifrost-configdrives-dynamic/templates/network_info.json.j2 @@ -1,23 +1,36 @@ +{% if node_network_info is defined %} +{{ node_network_info }} +{% else %} { "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 %} + { +{% if ipv4_interface_mac is defined %} + "id": "{{ nic.mac }}", +{% else %} +{% if loop.first %} + "id": "{{ node_default_network_interface }}", +{% else %} + "id": "{{ nic.mac }}", +{% endif %} + "type": "phy", + "ethernet_mac_address": "{{ nic.mac }}", "mtu":{{network_mtu}} +{% if loop.last %} } +{% else %} + }, +{% endif %} +{% endif %} +{% endfor %} ], "networks": [ +{% for nic in nics %} { - "id": "publicnet-ipv4", + "id": "ipv4-{{ nic.mac }}", +{% if (ipv4_interface_mac is defined) and (nic.mac == ipv4_interface_mac) %} + "link": "{{ nic.mac }}", "type": "ipv4", - "link": "{{ node_default_network_interface }}", "ip_address": "{{ ipv4_address }}", "netmask": "{{ipv4_subnet_mask}}", "dns_nameservers": [ @@ -30,7 +43,31 @@ with the information that we have available to us in nics. "gateway": "{{ipv4_gateway}}" } ] +{% elif loop.first %} + "link": "{{ node_default_network_interface }}", + "type": "ipv4", + "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}}" + } + ] +{% else %} + "type": "ipv4_dhcp", + "link": "{{ nic.mac }}" +{% endif %} +{% if loop.last %} } +{% else %} + }, +{% endif %} +{% endfor %} ], "services": [ { @@ -39,3 +76,4 @@ with the information that we have available to us in nics. } ] } +{% endif %} diff --git a/playbooks/roles/bifrost-configdrives-dynamic/templates/openstack_meta_data.json.j2 b/playbooks/roles/bifrost-configdrives-dynamic/templates/openstack_meta_data.json.j2 index f580341cc..e3cc207f7 100644 --- a/playbooks/roles/bifrost-configdrives-dynamic/templates/openstack_meta_data.json.j2 +++ b/playbooks/roles/bifrost-configdrives-dynamic/templates/openstack_meta_data.json.j2 @@ -1,11 +1,15 @@ { "availability_zone": "", +{% if write_interfaces_file | bool == true %} "files": [ { "content_path": "/content/0000", "path": "/etc/network/interfaces" } ], +{% else %} + "files": [], +{% endif %} "hostname": "{{ name }}", "name": "{{ name }}", "meta": {}, diff --git a/playbooks/roles/bifrost-create-dib-image/defaults/main.yml b/playbooks/roles/bifrost-create-dib-image/defaults/main.yml index 19fefce93..9fc937e8e 100644 --- a/playbooks/roles/bifrost-create-dib-image/defaults/main.yml +++ b/playbooks/roles/bifrost-create-dib-image/defaults/main.yml @@ -4,7 +4,6 @@ deploy_image_filename: "deployment_image.qcow2" deploy_image: "{{http_boot_folder}}/{{deploy_image_filename}}" dib_os_element: "ubuntu" dib_env_vars: - DIB_CLOUD_INIT_DATASOURCES: "ConfigDrive" ELEMENTS_PATH: "/opt/stack/diskimage-builder/elements" # extra_dib_elements is a space separated list of elements. extra_dib_elements: "" diff --git a/playbooks/roles/bifrost-create-dib-image/tasks/main.yml b/playbooks/roles/bifrost-create-dib-image/tasks/main.yml index 09bdcafcf..d593b7d19 100644 --- a/playbooks/roles/bifrost-create-dib-image/tasks/main.yml +++ b/playbooks/roles/bifrost-create-dib-image/tasks/main.yml @@ -19,6 +19,6 @@ stat: path={{ deploy_image }} register: test_image_present - name: "Initiate image build" - shell: disk-image-create -a amd64 -o "{{http_boot_folder}}/{{deploy_image_filename}}" -t qcow2 "{{dib_os_element}}" vm serial-console cloud-init-datasources "{{ extra_dib_elements}}" + shell: disk-image-create -a amd64 -o "{{http_boot_folder}}/{{deploy_image_filename}}" -t qcow2 "{{dib_os_element}}" vm serial-console simple-init "{{ extra_dib_elements}}" environment: dib_env_vars when: test_image_present.stat.exists == false diff --git a/scripts/test-bifrost.sh b/scripts/test-bifrost.sh index 9d23c735a..a69d568ac 100755 --- a/scripts/test-bifrost.sh +++ b/scripts/test-bifrost.sh @@ -35,7 +35,7 @@ ansible-playbook -vvvv -i inventory/localhost test-bifrost-create-vm.yaml export BIFROST_INVENTORY_SOURCE=/tmp/baremetal.csv # Execute the installation and VM startup test. -ansible-playbook -vvvv -i inventory/bifrost_inventory.py test-bifrost-dynamic.yaml -e use_cirros=true -e testing_user=cirros +ansible-playbook -vvvv -i inventory/bifrost_inventory.py test-bifrost-dynamic.yaml -e use_cirros=true -e testing_user=cirros -e write_interfaces_file=true EXITCODE=$? if [ $EXITCODE != 0 ]; then echo "****************************"