Merge "Enable kernel, net and process metrics for Telegraf"
diff --git a/README.rst b/README.rst
index a0a415a..6170e0b 100644
--- a/README.rst
+++ b/README.rst
@@ -291,6 +291,23 @@
           "cs_CZ.UTF-8 UTF-8":
             enabled: true
 
+Systemd settings:
+
+.. code-block:: yaml
+
+    linux:
+      system:
+        ...
+        systemd:
+          system:
+            Manager:
+              DefaultLimitNOFILE: 307200
+              DefaultLimitNPROC: 307200
+          user:
+            Manager:
+              DefaultLimitCPU: 2
+              DefaultLimitNPROC: 4
+
 Kernel
 ~~~~~~
 
@@ -317,6 +334,21 @@
             - tp_smapi
             - 8021q
 
+Configure or blacklist kernel modules with additional options to `/etc/modprobe.d` following example 
+will add `/etc/modprobe.d/nf_conntrack.conf` file with line `options nf_conntrack hashsize=262144`:
+
+.. code-block:: yaml
+
+    linux:
+      system:
+        kernel:
+          module:
+            nf_conntrack:
+              option:
+                hashsize: 262144
+
+
+
 Install specific kernel version and ensure all other kernel packages are
 not present. Also install extra modules and headers for this kernel:
 
@@ -346,7 +378,7 @@
 CPU
 ~~~
 
-Disable ondemand cpu mode service:
+Enable cpufreq governor for every cpu:
 
 .. code-block:: yaml
 
@@ -1025,6 +1057,7 @@
             enabled: true
             type: dpdk_ovs_port
             n_rxq: 2
+            pmd_rxq_affinity: "0:1,1:2"
             bridge: br-prv
             mtu: 9000
           br-prv:
@@ -1055,6 +1088,7 @@
             enabled: true
             type: dpdk_ovs_port
             n_rxq: 2
+            pmd_rxq_affinity: "0:1,1:2"
             mtu: 9000
           dpdk_first_nic:
             name: ${_param:primary_first_nic}
@@ -1064,6 +1098,7 @@
             enabled: true
             type: dpdk_ovs_port
             n_rxq: 2
+            pmd_rxq_affinity: "0:1,1:2"
             mtu: 9000
           dpdkbond0:
             enabled: true
diff --git a/linux/files/governor.conf.jinja b/linux/files/governor.conf.jinja
new file mode 100644
index 0000000..026a478
--- /dev/null
+++ b/linux/files/governor.conf.jinja
@@ -0,0 +1,3 @@
+{% for cpu_core in range(salt['grains.get']('num_cpus', 1)) %}
+devices/system/cpu/cpu{{ cpu_core }}/cpufreq/scaling_governor = {{ governor }}
+{% endfor %}
diff --git a/linux/files/modprobe.conf.jinja b/linux/files/modprobe.conf.jinja
new file mode 100644
index 0000000..2314bdb
--- /dev/null
+++ b/linux/files/modprobe.conf.jinja
@@ -0,0 +1,9 @@
+{% if module_content.get('blacklist', false) -%}
+blacklist {{ module_name }}
+{%- else -%}
+
+{%- for option, value in module_content.get('option', {}) | dictsort -%}
+options {{ module_name }} {{ option }}={{ value }}
+{%- endfor %}
+
+{%- endif %}
diff --git a/linux/files/systemd.conf b/linux/files/systemd.conf
new file mode 100644
index 0000000..36e01a5
--- /dev/null
+++ b/linux/files/systemd.conf
@@ -0,0 +1,7 @@
+{%- from "linux/map.jinja" import system with context -%}
+{%- for section, options in settings.iteritems() -%}
+[{{ section }}]
+{%- for option, value in options.iteritems() %}
+{{ option }}={{ value }}
+{%- endfor -%}
+{%- endfor -%}
diff --git a/linux/network/dpdk.sls b/linux/network/dpdk.sls
index 6ddd856..cadc599 100644
--- a/linux/network/dpdk.sls
+++ b/linux/network/dpdk.sls
@@ -115,6 +115,7 @@
 {# create override for openvswitch dependency for dpdk br-prv #}
 /etc/systemd/system/ifup@{{ interface_name }}.service.d/override.conf:
   file.managed:
+    - makedirs: true
     - require:
       - cmd: linux_network_dpdk_bridge_interface_{{ interface_name }}
     - contents: |
@@ -147,8 +148,8 @@
     - require:
       - cmd: linux_network_dpdk_bridge_interface_{{ interface.bridge }}
 
-  {# Multiqueue n_rxq and mtu setup on interfaces #}
-  {%- elif interface.type == 'dpdk_ovs_port' and (interface.n_rxq is defined or interface.mtu is defined) %}
+  {# Multiqueue n_rxq, pmd_rxq_affinity and mtu setup on interfaces #}
+  {%- elif interface.type == 'dpdk_ovs_port' and (interface.n_rxq is defined or interface.mtu is defined or interface.pmd_rxq_affinity is defined) %}
 
   {%- if interface.n_rxq is defined %}
 
@@ -160,6 +161,16 @@
 
   {%- endif %}
 
+  {%- if interface.pmd_rxq_affinity is defined %}
+
+linux_network_dpdk_bridge_port_interface_pmd_rxq_affinity_{{ interface_name }}:
+  cmd.run:
+    - name: "ovs-vsctl set Interface {{ interface_name }} other_config:pmd-rxq-affinity={{ interface.pmd_rxq_affinity }} "
+    - unless: |
+        ovs-vsctl get Interface {{ interface_name }} other_config | grep 'pmd-rxq-affinity="{{ interface.pmd_rxq_affinity }}"'
+
+  {%- endif %}
+
   {%- if interface.mtu is defined %}
 
 {# MTU ovs dpdk setup on interfaces #}
diff --git a/linux/system/cpu.sls b/linux/system/cpu.sls
index 658457d..5292585 100644
--- a/linux/system/cpu.sls
+++ b/linux/system/cpu.sls
@@ -1,9 +1,45 @@
 {%- 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
+
 ondemand_service_disable:
   service.dead:
-  - name: ondemand
-  - enable: false
+    - name: ondemand
+    - enable: false
 
-{%- endif %}
\ No newline at end of file
+{%- if grains.get('virtual', None) in ['physical', None] %}
+{#- Governor cannot be set in VMs, etc. #}
+
+/etc/sysfs.d/governor.conf:
+  file.managed:
+    - source: salt://linux/files/governor.conf.jinja
+    - template: jinja
+    - user: root
+    - group: root
+    - mode: 0644
+    - defaults:
+        governor: {{ system.cpu.governor }}
+
+{% for cpu_core in range(salt['grains.get']('num_cpus', 1)) %}
+
+governor_write_sysfs_cpu_core_{{ cpu_core }}:
+  module.run:
+    - name: sysfs.write
+    - key: devices/system/cpu/cpu{{ cpu_core }}/cpufreq/scaling_governor
+    - value: {{ system.cpu.governor }}
+
+{%- endfor %}
+
+{%- endif %}
+
+{%- endif %}
diff --git a/linux/system/group.sls b/linux/system/group.sls
index 2c1c769..d990889 100644
--- a/linux/system/group.sls
+++ b/linux/system/group.sls
@@ -7,7 +7,7 @@
 
 system_group_{{ group_name }}:
   group.present:
-  - name: {{ group.name }}
+  - name: {{ group.get('name', group_name) }}
   {%- if group.system is defined and group.system %}
   - system: True
   {%- endif %}
diff --git a/linux/system/init.sls b/linux/system/init.sls
index 5855bf5..13f1565 100644
--- a/linux/system/init.sls
+++ b/linux/system/init.sls
@@ -83,3 +83,6 @@
 {%- if system.service is defined %}
 - linux.system.service
 {%- endif %}
+{%- if system.systemd is defined %}
+- linux.system.systemd
+{%- endif %}
diff --git a/linux/system/job.sls b/linux/system/job.sls
index c0c6b5f..f0373a4 100644
--- a/linux/system/job.sls
+++ b/linux/system/job.sls
@@ -23,6 +23,10 @@
     {%- if job.dayweek is defined %}
     - dayweek: '{{ job.dayweek }}'
     {%- endif %}
+    {%- if job.user in system.get('user', {}).keys() %}
+    - require:
+      - user: system_user_{{ job.user }}
+    {%- endif %}
   {%- else %}
   cron.absent:
     - name: {{ job.command }}
diff --git a/linux/system/kernel.sls b/linux/system/kernel.sls
index 3c7619e..e3e6bd1 100644
--- a/linux/system/kernel.sls
+++ b/linux/system/kernel.sls
@@ -53,6 +53,21 @@
 
 {%- endfor %}
 
+{%- for module_name, module_content in system.kernel.get('module', {}).iteritems() %}
+
+/etc/modprobe.d/{{ module_name }}.conf:
+  file.managed:
+    - user: root
+    - group: root
+    - mode: 0644
+    - template: jinja
+    - source: salt://linux/files/modprobe.conf.jinja
+    - defaults:
+       module_content: {{ module_content }}
+       module_name: {{ module_name }}
+
+{%- endfor %}
+
 {%- for sysctl_name, sysctl_value in system.kernel.get('sysctl', {}).iteritems() %}
 
 linux_kernel_{{ sysctl_name }}:
diff --git a/linux/system/systemd.sls b/linux/system/systemd.sls
new file mode 100644
index 0000000..d5377f1
--- /dev/null
+++ b/linux/system/systemd.sls
@@ -0,0 +1,34 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled and grains.get('init', None) == 'systemd' %}
+
+{%- if system.systemd.system is defined %}
+linux_systemd_system_config:
+  file.managed:
+    - name: /etc/systemd/system.conf.d/90-salt.conf
+    - source: salt://linux/files/systemd.conf
+    - template: jinja
+    - makedirs: True
+    - defaults:
+        settings: {{ system.systemd.system }}
+    - watch_in:
+      - module: linux_systemd_reload
+{%- endif %}
+
+{%- if system.systemd.user is defined %}
+linux_systemd_user_config:
+  file.managed:
+    - name: /etc/systemd/user.conf.d/90-salt.conf
+    - source: salt://linux/files/systemd.conf
+    - template: jinja
+    - makedirs: True
+    - defaults:
+        settings: {{ system.systemd.user }}
+    - watch_in:
+      - module: linux_systemd_reload
+{%- endif %}
+
+linux_systemd_reload:
+  module.wait:
+  - name: service.systemctl_reload
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/system/user.sls b/linux/system/user.sls
index 70c9c51..5c6ba92 100644
--- a/linux/system/user.sls
+++ b/linux/system/user.sls
@@ -5,6 +5,14 @@
 
 {%- if user.enabled %}
 
+{%- set requires = [] %}
+{%- for group in user.get('groups', []) %}
+  {%- if group in system.get('group', {}).keys() %}
+    {%- do requires.append({'group': 'system_group_'+group}) %}
+  {%- endif %}
+{%- endfor %}
+
+
 system_user_{{ name }}:
   user.present:
   - name: {{ name }}
@@ -25,6 +33,7 @@
   {%- if user.uid is defined and user.uid %}
   - uid: {{ user.uid }}
   {%- endif %}
+  - require: {{ requires|yaml }}
 
 system_user_home_{{ user.home }}:
   file.directory:
diff --git a/tests/pillar/system.sls b/tests/pillar/system.sls
index 8d34cc6..58358f8 100644
--- a/tests/pillar/system.sls
+++ b/tests/pillar/system.sls
@@ -43,7 +43,8 @@
         full_name: Test User
         home: /home/test
         groups:
-          - root
+          - db-ops
+          - salt-ops
       salt_user1:
         enabled: true
         name: saltuser1
@@ -58,18 +59,19 @@
         uid: 9992
         full_name: Salt Sudo User2
         home: /home/saltuser2
+        groups:
+          - sudogroup1
     group:
-      testgroup:
+      test:
         enabled: true
         name: test
         gid: 9999
         system: true
       db-ops:
         enabled: true
-        name: testgroup
       salt-ops:
         enabled: true
-        name: sudogroup0
+        name: salt-ops
       sudogroup1:
         enabled: true
         name: sudogroup1