Add a data store for ironic inspector introspection data

In environments without Swift we are currently unable to store hardware
introspection data. The inspection_store container runs an nginx server
that supports a restricted Swift-like HTTP API using WebDAV that supports
upload and retrieval of introspection data.
This commit is contained in:
Mark Goddard 2017-09-01 18:09:02 +00:00
parent 00b6d7e7f0
commit 5304c0a489
19 changed files with 276 additions and 0 deletions

View File

@ -316,3 +316,14 @@ inspector_rules: "{{ inspector_rules_default + inspector_rules_extra }}"
# Ansible group containing switch hosts to which the workaround should be
# applied.
inspector_dell_switch_lldp_workaround_group:
###############################################################################
# Inspection store configuration.
# The inspection store provides a Swift-like service for storing inspection
# data which may be useful in environments without Swift.
# Whether the inspection data store is enabled.
inspector_store_enabled: "{{ not kolla_enable_swift | bool }}"
# Port on which the inspection data store should listen.
inspector_store_port: 8080

View File

@ -0,0 +1,16 @@
---
# Deploy/pull/reconfigure/upgrade inspection data store.
#
# Follows kolla-ansible service deployment patterns.
#
# Variables:
# action: One of deploy, destroy, pull, reconfigure, upgrade
- name: Ensure inspection store is deployed
hosts: controllers[0]
roles:
- role: inspection-store
inspection_store_enabled: "{{ inspector_store_enabled }}"
inspection_store_port: "{{ inspector_store_port }}"
# FIXME: Use kayobe_config_path?
inspection_store_config_path: "/etc/kayobe/inspection-store"

View File

@ -161,6 +161,13 @@
kolla_inspector_enable_discovery: "{{ inspector_enable_discovery }}"
kolla_inspector_discovery_enroll_node_driver: "{{ inspector_discovery_enroll_node_driver }}"
kolla_inspector_extra_kernel_options: "{{ inspector_extra_kernel_options }}"
# Ironic inspector swift store configuration. Currently only supports the
# 'fake' inspection store.
kolla_inspector_enable_swift: "{{ inspector_store_enabled }}"
kolla_inspector_swift_auth:
auth_type: token_endpoint
url: "http://{% raw %}{{ api_interface_address }}{% endraw %}:{{ inspector_store_port }}"
token: fake-token
# Ironic inspector's dnsmasq configuration.
kolla_inspector_dhcp_pool_start: "{{ inspection_net_name | net_inspection_allocation_pool_start }}"
kolla_inspector_dhcp_pool_end: "{{ inspection_net_name | net_inspection_allocation_pool_end }}"

View File

@ -8,4 +8,5 @@
# action: One of deploy, destroy, pull, reconfigure, upgrade
- include: docker-registry.yml
- include: inspection-store.yml
- include: opensm.yml

View File

@ -0,0 +1,37 @@
Inspection Store
================
Ironic inspector can make use of Swift to store introspection data. Not all
OpenStack deployments feature Swift, so it may be useful to provide a minimal
HTTP interface that emulates Swift for storing ironic inspector's introspection
data. This role deploys such an interface using nginx. Note that no
authentication mechanism is provided.
Requirements
------------
Docker engine should be running on the target system.
Role Variables
--------------
Dependencies
------------
The `docker-py` python package is required on the target system.
Example Playbook
----------------
The following playbook deploys an inspection store.
---
- hosts: all
roles:
- role: inspection-store
Author Information
------------------
- Mark Goddard (<mark@stackhpc.com>)

View File

@ -0,0 +1,37 @@
---
# Roughly follows kolla-ansible's service deployment patterns.
# Whether an inspection store is enabled.
inspection_store_enabled: true
# Service deployment definition.
inspection_store_services:
inspection_store:
container_name: inspection_store
enabled: "{{ inspection_store_enabled }}"
image: "{{ inspection_store_image_full }}"
ports:
- "{{ inspection_store_port }}:80"
volumes:
- "/etc/localtime:/etc/localtime:ro"
- "{{ inspection_store_config_path }}/nginx.conf:/etc/nginx/nginx.conf:ro"
- "inspection_store:/data"
# The port on which the inspection store server should listen.
inspection_store_port: 8080
# Path in which to store inspection store server configuration.
inspection_store_config_path: "/etc/inspection-store"
####################
# Inspection Store
####################
# NOTE: Namespace 'library' causes image task to always be changed and
# container to never update to new images.
inspection_store_namespace: ""
inspection_store_image: "{{ inspection_store ~ '/' if inspection_store | default else '' }}{{ inspection_store_namespace ~ '/' if inspection_store_namespace else '' }}nginx"
inspection_store_tag: "latest"
inspection_store_image_full: "{{ inspection_store_image }}:{{ inspection_store_tag }}"
inspection_store_restart_policy: "unless-stopped"
inspection_store_restart_retries: 10

View File

@ -0,0 +1,15 @@
---
- name: Restart inspection store container
docker_container:
name: "{{ item.value.container_name }}"
state: started
restart: True
with_dict: "{{ inspection_store_services }}"
when: item.value.enabled
- name: Ensure inspection store data directory exists
command: >
docker exec {{ inspection_store_services.inspection_store.container_name }}
bash -c "mkdir -p /data/ironic-inspector &&
chown nginx:nginx /data/ironic-inspector"
when: inspection_store_services.inspection_store.enabled

View File

@ -0,0 +1,17 @@
---
- name: Ensure inspection store configuration path exists
file:
path: "{{ inspection_store_config_path }}"
state: directory
owner: "{{ ansible_env.USER }}"
group: "{{ ansible_env.USER }}"
mode: 0750
become: True
- name: Ensure inspection store server is configured
template:
src: nginx.conf
dest: "{{ inspection_store_config_path }}/nginx.conf"
notify:
- Restart inspection store container
- Ensure inspection store data directory exists

View File

@ -0,0 +1,3 @@
---
- include: config.yml
- include: start.yml

View File

@ -0,0 +1,29 @@
---
- name: Ensure inspection store container is stopped
docker_container:
name: "{{ item.value.container_name }}"
state: "absent"
with_dict: "{{ inspection_store_services }}"
- name: Check whether inspection store volumes are present
command: docker volume inspect {{ volume }}
changed_when: False
with_subelements:
- "{{ inspection_store_services }}"
- volumes
when: "'/' not in volume"
failed_when:
- volume_result.rc != 0
- "'No such volume' not in volume_result.stderr"
vars:
volume: "{{ item.1.split(':')[0] }}"
register: volume_result
- name: Ensure inspection store volumes are absent
command: docker volume rm {{ volume }}
with_items: "{{ volume_result.results }}"
when:
- not item | skipped
- item.rc == 0
vars:
volume: "{{ item.item.1.split(':')[0] }}"

View File

@ -0,0 +1,2 @@
---
- include: "{{ action }}.yml"

View File

@ -0,0 +1,10 @@
---
- name: Pulling inspection store container image
docker_image:
name: "{{ item.value.image }}"
repository: "{{ item.value.image }}"
state: present
with_dict: "{{ inspection_store_services }}"
when:
- item.value.enabled
- action != 'destroy'

View File

@ -0,0 +1,2 @@
---
- include: deploy.yml

View File

@ -0,0 +1,15 @@
---
- name: Ensure inspection store container is running
docker_container:
image: "{{ item.value.image }}"
name: "{{ item.value.container_name }}"
ports: "{{ item.value.ports | default(omit) }}"
privileged: "{{ item.value.privileged | default(omit) }}"
read_only: "{{ item.value.read_only | default(omit) }}"
restart_policy: "{{ inspection_store_restart_policy }}"
restart_retries: "{{ inspection_store_restart_retries }}"
state: "{{ item.value.enabled | ternary('started', 'absent') }}"
volumes: "{{ item.value.volumes }}"
with_dict: "{{ inspection_store_services }}"
notify:
- Ensure inspection store data directory exists

View File

@ -0,0 +1,3 @@
---
- include: pull.yml
- include: deploy.yml

View File

@ -0,0 +1,40 @@
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
root /data;
location /ironic-inspector {
return 200 "";
}
location /ironic-inspector/ {
dav_methods PUT DELETE;
}
}
}

View File

@ -163,6 +163,13 @@ kolla_inspector_ipa_kernel_path:
# Mutually exclusive with kolla_inspector_ipa_ramdisk_upstream_url.
kolla_inspector_ipa_ramdisk_path:
# Whether to enable the Swift introspection data store.
kolla_inspector_enable_swift:
# Dict of authentication parameters for accessing the Swift introspection data
# store.
kolla_inspector_swift_auth: {}
# Free form extra configuration to append to ironic-inspector.conf.
kolla_extra_inspector:

View File

@ -27,7 +27,20 @@ always_store_ramdisk_logs = True
{% if kolla_inspector_enable_discovery %}
# Enable discovery when nodes do not exist in Ironic.
node_not_found_hook = enroll
{% endif %}
{% if kolla_inspector_enable_swift %}
store_data = swift
{% endif %}
{% if kolla_inspector_enable_swift %}
[swift]
{% for key, value in kolla_inspector_swift_auth.items() %}
{{ key }} = {{ value }}
{% endfor %}
{% endif %}
{% if kolla_inspector_enable_discovery %}
[discovery]
# The driver with which to enroll newly discovered nodes in Ironic.
enroll_node_driver = {{ kolla_inspector_discovery_enroll_node_driver }}

View File

@ -109,6 +109,17 @@
# applied.
#inspector_dell_switch_lldp_workaround_group:
###############################################################################
# Inspection store configuration.
# The inspection store provides a Swift-like service for storing inspection
# data which may be useful in environments without Swift.
# Whether the inspection data store is enabled.
#inspector_store_enabled:
# Port on which the inspection data store should listen.
#inspector_store_port:
###############################################################################
# Dummy variable to allow Ansible to accept this file.
workaround_ansible_issue_8743: yes