Merge "Add bond member status monitoring."
diff --git a/.kitchen.travis.yml b/.kitchen.travis.yml
new file mode 100644
index 0000000..a1d3e04
--- /dev/null
+++ b/.kitchen.travis.yml
@@ -0,0 +1,6 @@
+suites:
+
+ - name: <%= ENV['SUITE'] %>
+ provisioner:
+ pillars-from-files:
+ linux.sls: tests/pillar/<%= ENV['SUITE'] %>.sls
diff --git a/.travis.yml b/.travis.yml
index 577330b..3e54539 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,17 +22,19 @@
- bundle install
env:
- - PLATFORM=trevorj/salty-whales:trusty
- - PLATFORM=trevorj/salty-whales:xenial
-
+ - PLATFORM=trevorj/salty-whales:trusty SUITE=network
+ - PLATFORM=trevorj/salty-whales:xenial SUITE=network
+ # - PLATFORM=trevorj/salty-whales:trusty SUITE=storage
+ # - PLATFORM=trevorj/salty-whales:xenial SUITE=storage
+ - PLATFORM=trevorj/salty-whales:trusty SUITE=system
+ - PLATFORM=trevorj/salty-whales:xenial SUITE=system
before_script:
- set -o pipefail
- make test | tail
script:
- - test ! -e .kitchen.yml || bundle exec kitchen converge || true
- - test ! -e .kitchen.yml || bundle exec kitchen verify -t tests/integration
+ - KITCHEN_LOCAL_YAML=.kitchen.travis.yml bundle exec kitchen test -t tests/integration
notifications:
webhooks:
diff --git a/README.rst b/README.rst
index 9e1692b..6f81c5d 100644
--- a/README.rst
+++ b/README.rst
@@ -407,6 +407,25 @@
cpu:
governor: performance
+Sysfs
+~~~~~
+
+Install sysfsutils and set sysfs attributes:
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ sysfs:
+ scheduler:
+ block/sda/queue/scheduler: deadline
+ power:
+ mode:
+ power/state: 0660
+ owner:
+ power/state: "root:power"
+ devices/system/cpu/cpu0/cpufreq/scaling_governor: powersave
+
Huge Pages
~~~~~~~~~~~~
@@ -967,10 +986,9 @@
Configure global environment variables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Linux /etc/environment:
-``/etc/environment`` is for static system wide variable assignment after boot. Variable expansion is frequently not supported.
+Use ``/etc/environment`` for static system wide variable assignment after
+boot. Variable expansion is frequently not supported.
.. code-block:: yaml
@@ -1002,11 +1020,10 @@
- .local
Configure profile.d scripts
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Linux /etc/profile.d:
-The profile.d scripts are being sourced during .sh execution and support variable expansion in opposite to /etc/environment
-global settings in ``/etc/environment``.
+The profile.d scripts are being sourced during .sh execution and support
+variable expansion in opposite to /etc/environment global settings in
+``/etc/environment``.
.. code-block:: yaml
@@ -1029,11 +1046,11 @@
export NO_PROXY='.local'
Linux with hosts
-~~~~~~~~~~~~~~~~
Parameter purge_hosts will enforce whole /etc/hosts file, removing entries
that are not defined in model except defaults for both IPv4 and IPv6 localhost
and hostname + fqdn.
+
It's good to use this option if you want to ensure /etc/hosts is always in a
clean state however it's not enabled by default for safety.
@@ -1041,7 +1058,6 @@
linux:
network:
- ...
purge_hosts: true
host:
# No need to define this one if purge_hosts is true
@@ -1061,9 +1077,27 @@
- node2.domain.com
- service2.domain.com
+Linux with hosts collected from mine
+
+In this case all dns records defined within infrastrucuture will be passed to
+local hosts records or any DNS server. Only hosts with `grain` parameter to
+true will be propagated to the mine.
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ purge_hosts: true
+ mine_dns_records: true
+ host:
+ node1:
+ address: 192.168.10.200
+ grain: true
+ names:
+ - node2.domain.com
+ - service2.domain.com
Setup resolv.conf, nameservers, domain and search domains
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: yaml
@@ -1082,7 +1116,7 @@
- timeout: 2
- attempts: 2
-**setting custom TX queue length for tap interfaces**
+setting custom TX queue length for tap interfaces
.. code-block:: yaml
@@ -1091,7 +1125,6 @@
tap_custom_txqueuelen: 10000
DPDK OVS interfaces
---------------------
**DPDK OVS NIC**
diff --git a/_modules/linux_hosts.py b/_modules/linux_hosts.py
new file mode 100644
index 0000000..08741ec
--- /dev/null
+++ b/_modules/linux_hosts.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+'''
+Module for defining new filter for sorting
+host names/alias by FQDN first and alphabetically
+'''
+
+from jinja2 import Undefined
+
+def fqdn_sort_fn(n1, n2):
+ l1 = n1.split('.')
+ l2 = n2.split('.')
+ if len(l1) > len(l2):
+ return -1
+ if len(l1) < len(l2):
+ return 1
+ for i1, i2 in zip(l1, l2):
+ if i1 < i2:
+ return -1
+ if i1 > i2:
+ return 1
+ return 0
+
+def fqdn_sort_filter(iterable):
+ if iterable is None or isinstance(iterable, Undefined):
+ return iterable
+ # Do effective custom sorting of iterable here
+ return sorted(iterable, cmp=fqdn_sort_fn)
diff --git a/_modules/linux_netlink.py b/_modules/linux_netlink.py
index 9e6df55..52d8a1d 100644
--- a/_modules/linux_netlink.py
+++ b/_modules/linux_netlink.py
@@ -2,16 +2,15 @@
import re
-_alphanum_re = re.compile(r'^[a-z0-9]+$')
-_lo_re = re.compile(r'^lo$')
-
-def _filter(interface):
- return _alphanum_re.match(interface) and not _lo_re.match(interface)
-
-
-def ls():
+def ls(regex):
"""
Provide a list of network interfaces.
"""
+ _lo_re = re.compile(r'^lo$')
+ _alphanum_re = re.compile(regex)
+
+ def _filter(interface):
+ return _alphanum_re.match(interface) and not _lo_re.match(interface)
+
return filter(_filter, __salt__['grains.get']('ip_interfaces', {}).keys())
diff --git a/linux/files/hosts b/linux/files/hosts
index 66951f0..4971f6c 100644
--- a/linux/files/hosts
+++ b/linux/files/hosts
@@ -31,9 +31,19 @@
'ip6-allhosts'
],
} -%}
-{%- for name, host in network.host.iteritems() -%}
+{%- for name, host in host_dict.iteritems() -%}
+{%- for hname in host.names -%}
+{%- if hname in hosts.get('127.0.1.1', []) -%}
+{%- do hosts.pop('127.0.1.1') -%}
+{%- endif %}
+{%- endfor %}
{%- do hosts.update({host.address: host.names}) -%}
{%- endfor %}
{% for address, entries in hosts|dictsort %}
-{{ address }} {{ entries|join(' ') }}
+{%- if 'linux_hosts.fqdn_sort_filter' in salt.keys() %}
+{%- set sorted_entries = salt['linux_hosts.fqdn_sort_filter'](entries) -%}
+{%- else %}
+{%- set sorted_entries = entries -%}
+{%- endif %}
+{{ address }} {{ sorted_entries|join(' ') }}
{%- endfor %}
diff --git a/linux/files/sysfs.conf b/linux/files/sysfs.conf
new file mode 100644
index 0000000..513a53a
--- /dev/null
+++ b/linux/files/sysfs.conf
@@ -0,0 +1,16 @@
+# Sysfs file for {{ name }} managed by salt-minion(1)
+# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
+
+{%- for key, value in sysfs.iteritems() %}
+ {%- if key in ["mode", "owner"] %}
+ {%- for attr, val in value.iteritems() %}
+mode {{ attr }} = {{ val }}
+ {%- endfor %}
+ {%- else %}
+{{ key }} = {{ value }}
+ {%- endif %}
+{%- endfor %}
+
+{#-
+vim: syntax=jinja
+-#}
diff --git a/linux/map.jinja b/linux/map.jinja
index 05af281..a27906c 100644
--- a/linux/map.jinja
+++ b/linux/map.jinja
@@ -108,6 +108,7 @@
'host': 'none',
},
'host': {},
+ 'mine_dns_records': False,
'dhclient_config': '/etc/dhcp/dhclient.conf',
},
'Debian': {
@@ -123,6 +124,7 @@
'host': 'none'
},
'host': {},
+ 'mine_dns_records': False,
'dhclient_config': '/etc/dhcp/dhclient.conf',
},
'RedHat': {
@@ -137,6 +139,7 @@
'host': 'none'
},
'host': {},
+ 'mine_dns_records': False,
'dhclient_config': '/etc/dhcp/dhclient.conf',
},
}, grain='os_family', merge=salt['pillar.get']('linux:network')) %}
@@ -197,24 +200,29 @@
{% set monitoring = salt['grains.filter_by']({
'default': {
'zombie': {
- 'warn': 3,
- 'crit': 7,
+ 'warn': 3,
+ 'crit': 7,
},
'procs': {
- 'warn': 5000,
- 'crit': 10000,
+ 'warn': 5000,
+ 'crit': 10000,
},
'load': {
- 'warn': '6,4,2',
- 'crit': '12,8,4',
+ 'warn': '6,4,2',
+ 'crit': '12,8,4',
},
'swap': {
- 'warn': '50%',
- 'crit': '20%',
+ 'warn': '50%',
+ 'crit': '20%',
},
'disk': {
- 'warn': '15%',
- 'crit': '5%',
+ 'warn': '15%',
+ 'crit': '5%',
+ },
+ 'netlink': {
+ 'interfaces': [],
+ 'interface_regex': '^[a-z0-9]+$',
+ 'ignore_selected': False,
},
'cpu_idle_percentage': {
'warn': 10.0,
diff --git a/linux/meta/collectd.yml b/linux/meta/collectd.yml
index 7219cfd..0884365 100644
--- a/linux/meta/collectd.yml
+++ b/linux/meta/collectd.yml
@@ -3,10 +3,15 @@
linux_network_netlink:
plugin: netlink
template: linux/files/collectd_netlink.conf
- ignore_selected: false
- {%- if 'linux_netlink.ls' in salt.keys() %}
+ ignore_selected: {{ monitoring.netlink.ignore_selected }}
+ {%- if monitoring.netlink.interfaces is list and monitoring.netlink.interfaces|length > 0 %}
+ {%- set interfaces = monitoring.netlink.interfaces %}
+ {%- else %}
+ {%- set interfaces = salt['linux_netlink.ls'](monitoring.netlink.interface_regex) %}
+ {%- endif %}
+ {%- if interfaces %}
interfaces:
- {%- for interface_name in salt['linux_netlink.ls']() %}
+ {%- for interface_name in interfaces|sort %}
- {{ interface_name }}
{%- endfor %}
{%- endif %}
diff --git a/linux/meta/salt.yml b/linux/meta/salt.yml
index 0a07522..9ca9ee9 100644
--- a/linux/meta/salt.yml
+++ b/linux/meta/salt.yml
@@ -1,4 +1,4 @@
-{%- from "linux/map.jinja" import system with context -%}
+{%- from "linux/map.jinja" import system,network with context -%}
orchestrate:
system:
priority: 30
@@ -18,3 +18,12 @@
{%- endif %}
{%- endfor %}
{{ service_grains|yaml(False)|indent(4) }}
+ {%- set dns_records = [] %}
+ {%- for host_name, host in network.host.items() %}
+ {%- if host.get('grain', False) %}
+ {%- do host.pop('grain') %}
+ {%- do dns_records.append(host) %}
+ {%- endif %}
+ {%- endfor %}
+ dns_records:
+ dns_records: {{ dns_records|yaml }}
diff --git a/linux/network/host.sls b/linux/network/host.sls
index caa7f3b..14bd837 100644
--- a/linux/network/host.sls
+++ b/linux/network/host.sls
@@ -1,6 +1,21 @@
{%- from "linux/map.jinja" import network with context %}
{%- if network.enabled %}
+{%- set host_dict = network.host %}
+
+{%- if network.mine_dns_records %}
+
+{%- for node_name, node_grains in salt['mine.get']('*', 'grains.items').iteritems() %}
+{%- if node_grains.get('dns_records', []) is iterable %}
+{%- for record in node_grains.get('dns_records', []) %}
+{%- set record_key = node_name ~ '-' ~ loop.index %}
+{%- do host_dict.update({ record_key: {'address': record.address, 'names': record.names} }) %}
+{%- endfor %}
+{%- endif %}
+{%- endfor %}
+
+{%- endif %}
+
{%- if network.get('purge_hosts', false) %}
linux_hosts:
@@ -8,10 +23,12 @@
- name: /etc/hosts
- source: salt://linux/files/hosts
- template: jinja
+ - defaults:
+ host_dict: {{ host_dict|yaml }}
{%- else %}
-{%- for name, host in network.host.iteritems() %}
+{%- for name, host in host_dict.iteritems() %}
{%- if host.names is defined %}
diff --git a/linux/storage/disk.sls b/linux/storage/disk.sls
index 55b8920..4fc96e5 100644
--- a/linux/storage/disk.sls
+++ b/linux/storage/disk.sls
@@ -36,9 +36,18 @@
- module: create_disk_label_{{ disk_name }}
- pkg: xfsprogs
-{%- if partition.get('mkfs') %}
+{% set end_size = end_size + partition.size -%}
-{%- if partition.type == "xfs" %}
+{%- endfor %}
+
+probe_partions_{{ disk_name }}:
+ module.run:
+ - name: partition.probe
+ - device: {{ disk_name }}
+
+{%- for partition in disk.get('partitions', []) %}
+
+{%- if partition.get('mkfs') and partition.type == "xfs" %}
mkfs_partition_{{ disk_name }}_{{ loop.index }}:
module.run:
@@ -50,11 +59,8 @@
{%- endif %}
-{%- endif %}
-
-{% set end_size = end_size + partition.size -%}
-
{%- endfor %}
+
{%- endfor %}
{%- endif %}
diff --git a/linux/system/cpu.sls b/linux/system/cpu.sls
index 4bf6564..37c3c21 100644
--- a/linux/system/cpu.sls
+++ b/linux/system/cpu.sls
@@ -1,16 +1,8 @@
{%- from "linux/map.jinja" import system with context %}
{%- if system.cpu.governor is defined %}
-linux_sysfs_package:
- pkg.installed:
- - pkgs:
- - sysfsutils
- - refresh: true
-
-/etc/sysfs.d:
- file.directory:
- - require:
- - pkg: linux_sysfs_package
+include:
+ - linux.system.sysfs
ondemand_service_disable:
service.dead:
diff --git a/linux/system/init.sls b/linux/system/init.sls
index fe54147..0ba87aa 100644
--- a/linux/system/init.sls
+++ b/linux/system/init.sls
@@ -30,6 +30,9 @@
{%- if system.cpu is defined %}
- linux.system.cpu
{%- endif %}
+{%- if system.sysfs is defined %}
+- linux.system.sysfs
+{%- endif %}
{%- if system.locale|length > 0 %}
- linux.system.locale
{%- endif %}
diff --git a/linux/system/sysfs.sls b/linux/system/sysfs.sls
new file mode 100644
index 0000000..fdf1686
--- /dev/null
+++ b/linux/system/sysfs.sls
@@ -0,0 +1,42 @@
+{%- from "linux/map.jinja" import system with context %}
+
+linux_sysfs_package:
+ pkg.installed:
+ - pkgs:
+ - sysfsutils
+ - refresh: true
+
+/etc/sysfs.d:
+ file.directory:
+ - require:
+ - pkg: linux_sysfs_package
+
+{%- for name, sysfs in system.get('sysfs', {}).iteritems() %}
+
+/etc/sysfs.d/{{ name }}.conf:
+ file.managed:
+ - source: salt://linux/files/sysfs.conf
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 0644
+ - defaults:
+ name: {{ name }}
+ sysfs: {{ sysfs|yaml }}
+ - require:
+ - file: /etc/sysfs.d
+
+ {%- for key, value in sysfs.iteritems() %}
+ {%- if key not in ["mode", "owner"] %}
+ {%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %}
+ {#- Sysfs cannot be set in docker, LXC, etc. #}
+linux_sysfs_write_{{ name }}_{{ key }}:
+ module.run:
+ - name: sysfs.write
+ - key: {{ key }}
+ - value: {{ value }}
+ {%- endif %}
+ {%- endif %}
+ {%- endfor %}
+
+{%- endfor %}
diff --git a/tests/pillar/system.sls b/tests/pillar/system.sls
index 8d39312..f39fdde 100644
--- a/tests/pillar/system.sls
+++ b/tests/pillar/system.sls
@@ -15,6 +15,15 @@
default: "linux.ci.local$"
kernel:
isolcpu: 1,2,3,4
+ sysfs:
+ scheduler:
+ block/sda/queue/scheduler: deadline
+ power:
+ mode:
+ power/state: 0660
+ owner:
+ power/state: "root:power"
+ devices/system/cpu/cpu0/cpufreq/scaling_governor: powersave
motd:
- warning: |
#!/bin/sh