diff --git a/ansible/overcloud-introspection-data-save.yml b/ansible/overcloud-introspection-data-save.yml new file mode 100644 index 000000000..3b00a0794 --- /dev/null +++ b/ansible/overcloud-introspection-data-save.yml @@ -0,0 +1,64 @@ +--- +- name: Ensure the overcloud nodes' hardware introspection data is saved + hosts: overcloud + vars: + seed_host: "{{ groups['seed'][0] }}" + # Override this to save results to another location. + output_dir: "{{ lookup('env', 'PWD') }}/overcloud-introspection-data" + # Override this to set the output data format. One of json, yaml. + output_format: json + gather_facts: no + tasks: + - name: Query overcloud nodes' hardware introspection data + command: > + docker exec bifrost_deploy + bash -c '. env-vars && + export OS_URL=$IRONIC_URL + export OS_TOKEN=$OS_AUTH_TOKEN && + export BIFROST_INVENTORY_SOURCE=ironic && + ansible baremetal + --connection local + --inventory /etc/bifrost/inventory/ + -e @/etc/bifrost/bifrost.yml + -e @/etc/bifrost/dib.yml + --limit {{ inventory_hostname }} + -m shell + -a "env OS_URL=http://localhost:5050 openstack baremetal introspection data save {% raw %}{{ inventory_hostname }}{% endraw %}"' + register: save_result + changed_when: False + # Ignore errors, log a message later. + failed_when: False + delegate_to: "{{ seed_host }}" + vars: + # NOTE: Without this, the seed's ansible_host variable will not be + # respected when using delegate_to. + ansible_host: "{{ hostvars[seed_host].ansible_host | default(seed_host) }}" + + - name: Ensure introspection data output directory exists + local_action: + module: file + path: "{{ output_dir }}" + state: directory + + - name: Ensure introspection data is saved locally + local_action: + module: copy + content: "{{ introspection_data_map[output_format | lower] }}" + dest: "{{ output_dir }}/{{ inventory_hostname }}.{{ output_format | lower }}" + when: save_result.rc == 0 + vars: + introspection_data: "{{ save_result.stdout_lines[1:] | join('\n') | from_json }}" + introspection_data_json: "{{ introspection_data | to_nice_json(indent=4) }}" + introspection_data_yaml: "{{ introspection_data | to_nice_yaml }}" + introspection_data_map: + json: "{{ introspection_data_json }}" + yaml: "{{ introspection_data_yaml }}" + + - name: Log when introspection data could not be queried + debug: + msg: > + Could not query hardware introspection data for + {{ inventory_hostname }}. + Stdout: {{ save_result.stdout }}. + Stderr: {{ save_result.stderr }}. + when: save_result.rc != 0 diff --git a/doc/source/deployment.rst b/doc/source/deployment.rst index 65c8e43c3..b0235a817 100644 --- a/doc/source/deployment.rst +++ b/doc/source/deployment.rst @@ -207,6 +207,19 @@ to add them to the Kayobe and bifrost Ansible inventories:: (kayobe-venv) $ kayobe overcloud inventory discover +Saving Hardware Introspection Data +---------------------------------- + +If ironic inspector is in use on the seed host, introspection data will be +stored in the local nginx service. This data may be saved to the control +host:: + + (kayobe-venv) $ kayobe overcloud introspection data save + +``--output-dir`` may be used to specify the directory in which introspection +data files will be saved. ``--output-format`` may be used to set the format of +the files. + BIOS and RAID Configuration --------------------------- diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py index c6ea1b137..52d5fbce8 100644 --- a/kayobe/cli/commands.py +++ b/kayobe/cli/commands.py @@ -369,6 +369,39 @@ class OvercloudInventoryDiscover(KayobeAnsibleMixin, VaultMixin, Command): tags="config") +class OvercloudIntrospectionDataSave(KayobeAnsibleMixin, VaultMixin, Command): + """Save hardware introspection data for the overcloud. + + Save hardware introspection data from the seed's ironic inspector service + to the control host. + """ + + def get_parser(self, prog_name): + parser = super(OvercloudIntrospectionDataSave, self).get_parser( + prog_name) + group = parser.add_argument_group("Introspection data") + # Defaults for these are applied in the playbook. + group.add_argument("--output-dir", type=str, + help="Path to directory in which to save " + "introspection data. Default: " + "$PWD/overcloud-introspection-data") + group.add_argument("--output-format", type=str, + help="Format in which to save output data. One of " + "JSON or YAML. Default: JSON", + choices=["JSON", "YAML"]) + return parser + + def take_action(self, parsed_args): + self.app.LOG.debug("Saving introspection data") + extra_vars = {} + if parsed_args.output_dir: + extra_vars['output_dir'] = parsed_args.output_dir + if parsed_args.output_format: + extra_vars['output_format'] = parsed_args.output_format + playbooks = _build_playbook_list("overcloud-introspection-data-save") + self.run_kayobe_playbooks(parsed_args, playbooks, extra_vars=extra_vars) + + class OvercloudBIOSRAIDConfigure(KayobeAnsibleMixin, VaultMixin, Command): """Configure BIOS and RAID for the overcloud hosts.""" diff --git a/setup.py b/setup.py index 524c721ce..c21e4d0eb 100644 --- a/setup.py +++ b/setup.py @@ -62,6 +62,7 @@ setup( 'overcloud_deprovision = kayobe.cli.commands:OvercloudDeprovision', 'overcloud_hardware_inspect = kayobe.cli.commands:OvercloudHardwareInspect', 'overcloud_host_configure = kayobe.cli.commands:OvercloudHostConfigure', + 'overcloud_introspection_data_save = kayobe.cli.commands:OvercloudIntrospectionDataSave', 'overcloud_inventory_discover = kayobe.cli.commands:OvercloudInventoryDiscover', 'overcloud_post_configure = kayobe.cli.commands:OvercloudPostConfigure', 'overcloud_provision = kayobe.cli.commands:OvercloudProvision',