Initial commit
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..9299a80
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,6 @@
+linux-formula
+=============
+
+0.0.1 (2015-08-03)
+
+- Initial formula setup
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8e80b12
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2014-2015 tcp cloud a. s.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..1bd6f32
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,357 @@
+
+=====
+Linux
+=====
+
+Linux Operating Systems.
+
+* Ubuntu
+* CentOS
+* RedHat
+* Fedora
+* Arch
+
+Sample pillars
+==============
+
+Linux system
+------------
+
+Basic Linux box
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ enabled: true
+ name: 'node1'
+ domain: 'domain.com'
+ cluster: 'system'
+ environment: prod
+ timezone: 'Europe/Prague'
+ utc: true
+
+Linux with system users, sowe with password set
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ ...
+ user:
+ jdoe:
+ name: 'jdoe'
+ enabled: true
+ sudo: true
+ shell: /bin/bash
+ full_name: 'Jonh Doe'
+ home: '/home/jdoe'
+ email: 'jonh@doe.com'
+ jsmith:
+ name: 'jsmith'
+ enabled: true
+ full_name: 'Password'
+ home: '/home/jsmith'
+ password: userpassword
+
+Linux with package, latest version
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ ...
+ package:
+ package-name:
+ version: latest
+
+Linux with package from certail repo, version with no upgrades
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ ...
+ package:
+ package-name:
+ version: 2132.323
+ repo: 'custom-repo'
+ hold: true
+
+Linux with package from certail repo, version with no GPG verification
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ ...
+ package:
+ package-name:
+ version: 2132.323
+ repo: 'custom-repo'
+ verify: false
+
+Linux with cron jobs
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ ...
+ job:
+ cmd1:
+ command: '/cmd/to/run'
+ enabled: true
+ user: 'root'
+ hour: 2
+ minute: 0
+
+Repositories
+~~~~~~~~~~~~
+
+RedHat based Linux with additional OpenStack repo
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ ...
+ repo:
+ rdo-icehouse:
+ enabled: true
+ source: 'http://repos.fedorapeople.org/repos/openstack/openstack-icehouse/epel-6/'
+ pgpcheck: 0
+
+Ensure system repository to use czech Debian mirror (``default: true``)
+Also pin it's packages with priority 900.
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ repo:
+ debian:
+ default: true
+ source: "deb http://ftp.cz.debian.org/debian/ jessie main contrib non-free"
+ # Import signing key from URL if needed
+ key_url: "http://dummy.com/public.gpg"
+ pin:
+ - pin: 'origin "ftp.cz.debian.org"'
+ priority: 900
+ package: '*'
+
+Linux network
+-------------
+
+Linux with network manager
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ enabled: true
+ network_manager: true
+
+Linux with default static network interfaces, default gateway interface and DNS servers
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ enabled: true
+ interface:
+ eth0:
+ enabled: true
+ type: eth
+ address: 192.168.0.102
+ netmask: 255.255.255.0
+ gateway: 192.168.0.1
+ name_servers:
+ - 8.8.8.8
+ - 8.8.4.4
+ mtu: 1500
+
+Linux with bonded interfaces
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ enabled: true
+ interface:
+ eth0:
+ type: eth
+ ...
+ eth1:
+ type: eth
+ ...
+ bond0:
+ enabled: true
+ type: bond
+ address: 192.168.0.102
+ netmask: 255.255.255.0
+ mtu: 1500
+ use_in:
+ - interface: ${linux:interface:eth0}
+ - interface: ${linux:interface:eth0}
+
+Linux with wireless interface parameters
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ enabled: true
+ gateway: 10.0.0.1
+ default_interface: eth0
+ interface:
+ wlan0:
+ type: eth
+ wireless:
+ essid: example
+ key: example_key
+ security: wpa
+ priority: 1
+
+Linux networks with routes defined
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ enabled: true
+ gateway: 10.0.0.1
+ default_interface: eth0
+ interface:
+ eth0:
+ type: eth
+ route:
+ default:
+ address: 192.168.0.123
+ netmask: 255.255.255.0
+ gateway: 192.168.0.1
+
+Native Linux Bridges
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ interface:
+ eth1:
+ enabled: true
+ type: eth
+ proto: manual
+ up_cmds:
+ - ip address add 0/0 dev $IFACE
+ - ip link set $IFACE up
+ down_cmds:
+ - ip link set $IFACE down
+ br-ex:
+ enabled: true
+ type: bridge
+ address: ${linux:network:host:public_local:address}
+ netmask: 255.255.255.0
+ use_interfaces:
+ - eth1
+
+OpenVswitch Bridges
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ bridge: openvswitch
+ interface:
+ eth1:
+ enabled: true
+ type: eth
+ proto: manual
+ up_cmds:
+ - ip address add 0/0 dev $IFACE
+ - ip link set $IFACE up
+ down_cmds:
+ - ip link set $IFACE down
+ br-ex:
+ enabled: true
+ type: bridge
+ address: ${linux:network:host:public_local:address}
+ netmask: 255.255.255.0
+ use_interfaces:
+ - eth1
+
+Linux with proxy
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ ...
+ proxy:
+ host: proxy.domain.com
+ port: 3128
+
+Linux with hosts
+
+.. code-block:: yaml
+
+ linux:
+ network:
+ ...
+ host:
+ node1:
+ address: 192.168.10.200
+ names:
+ - node2.domain.com
+ - service2.domain.com
+ node2:
+ address: 192.168.10.201
+ names:
+ - node2.domain.com
+ - service2.domain.com
+
+Linux storage pillars
+---------------------
+
+Linux with mounted Samba
+
+.. code-block:: yaml
+
+ linux:
+ storage:
+ enabled: true
+ mount:
+ samba1:
+ - path: /media/myuser/public/
+ - device: //192.168.0.1/storage
+ - file_system: cifs
+ - options: guest,uid=myuser,iocharset=utf8,file_mode=0777,dir_mode=0777,noperm
+
+Linux with file swap
+
+.. code-block:: yaml
+
+ linux:
+ storage:
+ enabled: true
+ swap:
+ file:
+ enabled: true
+ engine: file
+ device: /swapfile
+ size: 1024
+
+Usage
+=====
+
+Set mtu of network interface eth0 to 1400
+
+.. code-block:: bash
+
+ ip link set dev eth0 mtu 1400
+
+Read more
+=========
+
+* https://www.archlinux.org/
+* http://askubuntu.com/questions/175172/how-do-i-configure-proxies-in-ubuntu-server-or-minimal-cli-ubuntu
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..3b04cfb
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.2
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..f992752
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,11 @@
+salt-formula-linux (0.2) trusty; urgency=medium
+
+ * First public release
+
+ -- Filip Pytloun <filip.pytloun@tcpcloud.eu> Tue, 06 Oct 2015 16:38:46 +0200
+
+salt-formula-linux (0.1) trusty; urgency=medium
+
+ * Initial release
+
+ -- Ales Komarek <ales.komarek@tcpcloud.eu> Thu, 13 Aug 2015 23:23:41 +0200
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..ce2b461
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,15 @@
+Source: salt-formula-linux
+Maintainer: Ales Komarek <ales.komarek@tcpcloud.eu>
+Section: admin
+Priority: optional
+Build-Depends: debhelper (>= 9)
+Standards-Version: 3.9.6
+Homepage: http://www.tcpcloud.eu
+Vcs-Browser: https://github.com/tcpcloud/salt-formula-linux
+Vcs-Git: https://github.com/tcpcloud/salt-formula-linux.git
+
+Package: salt-formula-linux
+Architecture: all
+Depends: ${misc:Depends}, salt-master, reclass
+Description: Linux salt formula
+ Configure Linux operating system.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..22bb6ee
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,15 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: salt-formula-linux
+Upstream-Contact: Ales Komarek <ales.komarek@tcpcloud.eu>
+Source: https://github.com/tcpcloud/salt-formula-linux
+
+Files: *
+Copyright: 2014-2015 tcp cloud a.s.
+License: Apache-2.0
+ Copyright (C) 2014-2015 tcp cloud a.s.
+ .
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ .
+ On a Debian system you can find a copy of this license in
+ /usr/share/common-licenses/Apache-2.0.
diff --git a/debian/docs b/debian/docs
new file mode 100644
index 0000000..d585829
--- /dev/null
+++ b/debian/docs
@@ -0,0 +1,3 @@
+README.rst
+CHANGELOG.rst
+VERSION
diff --git a/debian/install b/debian/install
new file mode 100644
index 0000000..aaeeacc
--- /dev/null
+++ b/debian/install
@@ -0,0 +1,2 @@
+linux/* /usr/share/salt-formulas/env/linux/
+metadata/service/* /usr/share/salt-formulas/reclass/service/linux/
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..abde6ef
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,5 @@
+#!/usr/bin/make -f
+
+%:
+ dh $@
+
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/linux/files/95proxies b/linux/files/95proxies
new file mode 100644
index 0000000..5bbdaea
--- /dev/null
+++ b/linux/files/95proxies
@@ -0,0 +1,4 @@
+{%- from "linux/map.jinja" import network with context %}
+Acquire::http::proxy "http://{{ network.proxy.host }}:{{ network.proxy.port }}/";
+Acquire::ftp::proxy "ftp://{{ network.proxy.host }}:{{ network.proxy.port }}/";
+Acquire::https::proxy "https://{{ network.proxy.host }}:{{ network.proxy.port }}/";
\ No newline at end of file
diff --git a/linux/files/collectd.conf b/linux/files/collectd.conf
new file mode 100644
index 0000000..02c0101
--- /dev/null
+++ b/linux/files/collectd.conf
@@ -0,0 +1,39 @@
+LoadPlugin cpu
+LoadPlugin df
+LoadPlugin disk
+LoadPlugin entropy
+LoadPlugin interface
+LoadPlugin memory
+LoadPlugin processes
+LoadPlugin swap
+LoadPlugin uptime
+LoadPlugin users
+
+<Plugin df>
+# Device "/dev/sda1"
+# Device "192.168.0.2:/mnt/nfs"
+# MountPoint "/home"
+# FSType "ext3"
+
+ # ignore rootfs; else, the root file-system would appear twice, causing
+ # one of the updates to fail and spam the log
+ FSType rootfs
+ # ignore the usual virtual / temporary file-systems
+ FSType sysfs
+ FSType proc
+ FSType devtmpfs
+ FSType devpts
+ FSType tmpfs
+ FSType fusectl
+ FSType cgroup
+ IgnoreSelected true
+# ReportByDevice false
+# ReportReserved false
+# ReportInodes false
+</Plugin>
+
+<Plugin disk>
+# Disk "hda"
+# Disk "/sda[23]/"
+ IgnoreSelected true
+</Plugin>
diff --git a/linux/files/hostname b/linux/files/hostname
new file mode 100644
index 0000000..b5ec334
--- /dev/null
+++ b/linux/files/hostname
@@ -0,0 +1 @@
+{{ pillar.linux.system.name }}
\ No newline at end of file
diff --git a/linux/files/logstash-filter.conf b/linux/files/logstash-filter.conf
new file mode 100644
index 0000000..acce463
--- /dev/null
+++ b/linux/files/logstash-filter.conf
@@ -0,0 +1,13 @@
+filter {
+ if [type] == "syslog" {
+ grok {
+ match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }
+ add_field => [ "received_at", "%{@timestamp}" ]
+ add_field => [ "received_from", "%{host}" ]
+ }
+ syslog_pri { }
+ date {
+ match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
+ }
+ }
+}
diff --git a/linux/files/logstash-forwarder.conf b/linux/files/logstash-forwarder.conf
new file mode 100644
index 0000000..660093b
--- /dev/null
+++ b/linux/files/logstash-forwarder.conf
@@ -0,0 +1,7 @@
+{
+ "paths": [
+ "/var/log/syslog",
+ "/var/log/auth.log"
+ ],
+ "fields": { "type": "syslog" }
+}
diff --git a/linux/files/multipath.conf b/linux/files/multipath.conf
new file mode 100644
index 0000000..3d8cce7
--- /dev/null
+++ b/linux/files/multipath.conf
@@ -0,0 +1,98 @@
+{%- from "linux/map.jinja" import storage with context %}
+##
+## This is a template multipath-tools configuration file
+## Uncomment the lines relevent to your environment
+##
+{% set backend = storage.get('backend', 'default') %}
+
+{%- if backend in ['hitachi', 'hds', 'HDS'] %}
+
+defaults {
+# udev_dir /dev
+# polling_interval 10
+# selector "round-robin 0"
+# path_grouping_policy multibus
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# prio const
+# path_checker directio
+# rr_min_io 100
+# flush_on_last_del no
+# max_fds 8192
+# rr_weight priorities
+# failback immediate
+# no_path_retry fail
+# queue_without_daemon no
+ user_friendly_names no
+# mode 644
+# uid 0
+# gid disk
+}
+
+{%- elif backend in ['fujitsu'] %}
+defaults {
+ user_friendly_names no
+}
+blacklist {
+ wwid "355cd2e404b76b*"
+}
+devices {
+ device {
+ vendor "FUJITSU"
+ product "ETERNUS_DXL"
+ prio alua
+ path_grouping_policy group_by_prio
+ path_selector "round-robin 0"
+ failback immediate
+ no_path_retry 0
+ path_checker tur
+ dev_loss_tmo 2097151
+ fast_io_fail_tmo 1
+ }
+}
+
+{%- else %}
+
+defaults {
+ getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+ user_friendly_names no
+}
+
+blacklist {
+# wwid 26353900f02796769
+# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
+# devnode "^hd[a-z][[0-9]*]"
+# device {
+# vendor DEC.*
+# product MSA[15]00
+# }
+ #
+ # POZOR - filtrace vseho krome blacklistovanych veci
+ #
+# wwid "*"
+}
+blacklist_exceptions {
+# devnode "^dasd[c-d]+[0-9]*"
+# wwid "IBM.75000000092461.4d00.34"
+# wwid 3600507680280050cd000000000000035
+# wwid 3600507680280050cd000000000000030
+# wwid 3600507680280050cd0000000000000ac
+# wwid 3600507680280050cd0000000000003df
+ wwid "*"
+}
+devices {
+ device {
+ vendor "IBM"
+ product "2145"
+ path_grouping_policy group_by_prio
+ getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+ features "1 queue_if_no_path"
+ prio alua
+ path_checker tur
+ failback immediate
+ no_path_retry "5"
+ rr_min_io 1
+ polling_interval 30
+ dev_loss_tmo 120
+ }
+}
+{%- endif %}
diff --git a/linux/files/multipath.conf.hds b/linux/files/multipath.conf.hds
new file mode 100644
index 0000000..0bc246f
--- /dev/null
+++ b/linux/files/multipath.conf.hds
@@ -0,0 +1,24 @@
+##
+## This is a template multipath-tools configuration file
+## Uncomment the lines relevent to your environment
+##
+defaults {
+# udev_dir /dev
+# polling_interval 10
+# selector "round-robin 0"
+# path_grouping_policy multibus
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# prio const
+# path_checker directio
+# rr_min_io 100
+# flush_on_last_del no
+# max_fds 8192
+# rr_weight priorities
+# failback immediate
+# no_path_retry fail
+# queue_without_daemon no
+ user_friendly_names no
+# mode 644
+# uid 0
+# gid disk
+}
diff --git a/linux/files/preferences_repo b/linux/files/preferences_repo
new file mode 100644
index 0000000..603d313
--- /dev/null
+++ b/linux/files/preferences_repo
@@ -0,0 +1,8 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- set repo = system.repo[repo_name] %}
+{%- for pin in repo.pin %}
+{%- set package = pin.get('package', '*') %}
+Package: {{ package }}
+Pin: {{ pin.pin }}
+Pin-Priority: {{ pin.priority }}
+{% endfor %}
diff --git a/linux/files/proxy.sh b/linux/files/proxy.sh
new file mode 100644
index 0000000..f2dc031
--- /dev/null
+++ b/linux/files/proxy.sh
@@ -0,0 +1,9 @@
+{%- from "linux/map.jinja" import network with context %}
+export http_proxy="http://{{ network.proxy.host }}:{{ network.proxy.port }}/"
+export https_proxy="http://{{ network.proxy.host }}:{{ network.proxy.port }}/"
+export ftp_proxy="http://{{ network.proxy.host }}:{{ network.proxy.port }}/"
+export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"
+export HTTP_PROXY="http://{{ network.proxy.host }}:{{ network.proxy.port }}/"
+export HTTPS_PROXY="http://{{ network.proxy.host }}:{{ network.proxy.port }}/"
+export FTP_PROXY="http://{{ network.proxy.host }}:{{ network.proxy.port }}/"
+export NO_PROXY="localhost,127.0.0.1,localaddress,.localdomain.com"
\ No newline at end of file
diff --git a/linux/files/sensu.conf b/linux/files/sensu.conf
new file mode 100644
index 0000000..460bce7
--- /dev/null
+++ b/linux/files/sensu.conf
@@ -0,0 +1,36 @@
+local_linux_system_zombie_procs:
+ command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_procs -w 1 -c 5 -s Z"
+ interval: 60
+ occurrences: 3
+ subscribers:
+ - local-linux-system
+local_linux_system_total_procs:
+ command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_procs -w 1500 -c 3000"
+ interval: 60
+ occurrences: 5
+ subscribers:
+ - local-linux-system
+local_linux_system_load:
+ command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_load -r -w 6,4,2 -c 12,8,4"
+ interval: 60
+ occurrences: 1
+ subscribers:
+ - local-linux-system
+local_linux_storage_swap_usage:
+ command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_swap -a -w 50% -c 20%"
+ interval: 60
+ occurrences: 1
+ subscribers:
+ - local-linux-storage
+local_linux_storage_disk_usage:
+ command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_disk -w 15% -c 5% -p / -p /var -p /usr -p /tmp -p /var/log"
+ interval: 60
+ occurrences: 1
+ subscribers:
+ - local-linux-storage
+local_linux_network_fqdn:
+ command: "PATH=$PATH:/etc/sensu/plugins check_fqdn.py -n :::hostname::: -f :::fqdn:::"
+ interval: 60
+ occurrences: 1
+ subscribers:
+ - local-linux-network
diff --git a/linux/files/sources.list b/linux/files/sources.list
new file mode 100644
index 0000000..ed41e7b
--- /dev/null
+++ b/linux/files/sources.list
@@ -0,0 +1,4 @@
+{%- for name, repo in default_repos.iteritems() %}
+# Repository {{ name }}
+{{ repo.source }}
+{%- endfor %}
diff --git a/linux/files/sudoer b/linux/files/sudoer
new file mode 100644
index 0000000..3b682af
--- /dev/null
+++ b/linux/files/sudoer
@@ -0,0 +1,5 @@
+# managed by salt
+
+# user {{ user_name }} is system administrator.
+# It has passwordless sudo functionality.
+{{ user_name }} ALL=(ALL) NOPASSWD:ALL
diff --git a/linux/files/wireless b/linux/files/wireless
new file mode 100644
index 0000000..4ae91f9
--- /dev/null
+++ b/linux/files/wireless
@@ -0,0 +1,8 @@
+{%- set interface = salt['pillar.get']('linux:network:interface:'+interface_name) %}
+Interface={{ interface_name }}
+Connection=wireless
+Security={{ interface.wireless.security }}
+ESSID={{ interface.wireless.essid }}
+IP=dhcp
+Key={{ interface.wireless.key }}
+Priority={{ interface.wireless.get('priority', '1') }}
diff --git a/linux/init.sls b/linux/init.sls
new file mode 100644
index 0000000..1fdc5ed
--- /dev/null
+++ b/linux/init.sls
@@ -0,0 +1,12 @@
+{%- if pillar.linux is defined %}
+include:
+{%- if pillar.linux.system is defined %}
+- linux.system
+{%- endif %}
+{%- if pillar.linux.network is defined %}
+- linux.network
+{%- endif %}
+{%- if pillar.linux.storage is defined %}
+- linux.storage
+{%- endif %}
+{%- endif %}
\ No newline at end of file
diff --git a/linux/map.jinja b/linux/map.jinja
new file mode 100644
index 0000000..66dbce0
--- /dev/null
+++ b/linux/map.jinja
@@ -0,0 +1,117 @@
+{% set system = salt['grains.filter_by']({
+ 'Arch': {
+ 'pkgs': ['sudo', 'vim', 'wget'],
+ 'utc': true,
+ 'user': {},
+ 'group': {},
+ 'job': {},
+ 'repo': {},
+ 'package': {},
+ 'selinux': 'permissive',
+ 'ca_certs_dir': '/usr/local/share/ca-certificates',
+ },
+ 'Debian': {
+ 'pkgs': ['python-apt','vim'],
+ 'utc': true,
+ 'user': {},
+ 'group': {},
+ 'job': {},
+ 'repo': {},
+ 'package': {},
+ 'selinux': 'permissive',
+ 'ca_certs_dir': '/usr/local/share/ca-certificates',
+ },
+ 'RedHat': {
+ 'pkgs': ['policycoreutils', 'policycoreutils-python', 'vim-enhanced', 'telnet', 'wget'],
+ 'utc': true,
+ 'user': {},
+ 'group': {},
+ 'job': {},
+ 'repo': {},
+ 'package': {},
+ 'selinux': 'permissive',
+ 'ca_certs_dir': '/usr/local/share/ca-certificates',
+ },
+}, grain='os_family', merge=salt['pillar.get']('linux:system')) %}
+
+{# 'network_name', #}
+
+{% set interface_params = [
+ 'gateway',
+ 'mtu',
+ 'network',
+ 'broadcast',
+ 'master',
+ 'miimon',
+ 'mode',
+ 'lacp-rate',
+ 'dns-search',
+ 'up_cmds',
+ 'pre_up_cmds',
+ 'post_up_cmds',
+ 'down_cmds',
+ 'pre_down_cmds',
+ 'post_down_cmds',
+] %}
+
+{% set network = salt['grains.filter_by']({
+ 'Arch': {
+ 'pkgs': ['wpa_supplicant', 'dhclient', 'wireless_tools'],
+ 'bridge_pkgs': ['bridge-utils'],
+ 'ovs_pkgs': ['openvswitch-switch'],
+ 'hostname_file': '/etc/hostname',
+ 'network_manager': False,
+ 'interface': {},
+ 'interface_params': interface_params,
+ 'bridge': 'none',
+ 'proxy': {
+ 'host': 'none',
+ },
+ 'host': {},
+ },
+ 'Debian': {
+ 'hostname_file': '/etc/hostname',
+ 'bridge_pkgs': ['bridge-utils'],
+ 'ovs_pkgs': ['openvswitch-switch'],
+ 'network_manager': False,
+ 'interface': {},
+ 'interface_params': interface_params,
+ 'bridge': 'none',
+ 'proxy': {
+ 'host': 'none',
+ },
+ 'host': {},
+ },
+ 'RedHat': {
+ 'bridge_pkgs': ['bridge-utils'],
+ 'ovs_pkgs': ['openvswitch-switch'],
+ 'hostname_file': '/etc/sysconfig/network',
+ 'network_manager': False,
+ 'interface': {},
+ 'interface_params': interface_params,
+ 'bridge': 'none',
+ 'proxy': {
+ 'host': 'none',
+ },
+ 'host': {},
+ },
+}, grain='os_family', merge=salt['pillar.get']('linux:network')) %}
+
+{% set storage = salt['grains.filter_by']({
+ 'Arch': {
+ 'mount': {},
+ 'swap': {},
+ 'multipath': False,
+ },
+ 'Debian': {
+ 'mount': {},
+ 'swap': {},
+ 'multipath': False,
+ 'multipath_pkgs': ['multipath-tools']
+ },
+ 'RedHat': {
+ 'mount': {},
+ 'swap': {},
+ 'multipath': False,
+ },
+}, grain='os_family', merge=salt['pillar.get']('linux:storage')) %}
diff --git a/linux/network/host.sls b/linux/network/host.sls
new file mode 100644
index 0000000..8254f4f
--- /dev/null
+++ b/linux/network/host.sls
@@ -0,0 +1,17 @@
+{%- from "linux/map.jinja" import network with context %}
+{%- if network.enabled %}
+
+{%- for name, host in network.host.iteritems() %}
+
+{%- if host.names is defined %}
+
+linux_host_{{ name }}:
+ host.present:
+ - ip: {{ host.address }}
+ - names: {{ host.names }}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/network/hostname.sls b/linux/network/hostname.sls
new file mode 100644
index 0000000..7c1594a
--- /dev/null
+++ b/linux/network/hostname.sls
@@ -0,0 +1,32 @@
+{%- from "linux/map.jinja" import network with context %}
+{%- if network.enabled %}
+
+{%- if grains.os_family in ['Arch', 'Debian'] %}
+
+linux_hostname_file:
+ file.managed:
+ - name: {{ network.hostname_file }}
+ - source: salt://linux/files/hostname
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 644
+ - watch_in:
+ - cmd: linux_enforce_hostname
+
+{%- endif %}
+
+linux_enforce_hostname:
+ cmd.wait:
+ - name: hostname {{ network.hostname }}
+
+{#
+linux_hostname_hosts:
+ host.present:
+ - ip: {{ grains.ip4_interfaces[network.get('default_interface', 'eth0')][0] }}
+ - names:
+ - {{ network.fqdn }}
+ - {{ network.hostname }}
+#}
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/network/init.sls b/linux/network/init.sls
new file mode 100644
index 0000000..2238cdd
--- /dev/null
+++ b/linux/network/init.sls
@@ -0,0 +1,10 @@
+{%- from "linux/map.jinja" import network with context %}
+include:
+- linux.network.hostname
+{%- if network.host|length > 0 %}
+- linux.network.host
+{%- endif %}
+{%- if network.interface|length > 0 %}
+- linux.network.interface
+{%- endif %}
+- linux.network.proxy
diff --git a/linux/network/interface.sls b/linux/network/interface.sls
new file mode 100644
index 0000000..70d7d3d
--- /dev/null
+++ b/linux/network/interface.sls
@@ -0,0 +1,209 @@
+{%- from "linux/map.jinja" import network with context %}
+{%- from "linux/map.jinja" import system with context %}
+{%- if network.enabled %}
+
+{%- macro set_param(param_name, param_dict) -%}
+{%- if param_dict.get(param_name, False) -%}
+- {{ param_name }}: {{ param_dict[param_name] }}
+{%- endif -%}
+{%- endmacro -%}
+
+{%- if network.bridge != 'none' %}
+
+linux_network_bridge_pkgs:
+ pkg.installed:
+ {%- if network.bridge == 'openvswitch' %}
+ - names: {{ network.ovs_pkgs }}
+ {%- else %}
+ - names: {{ network.bridge_pkgs }}
+ {%- endif %}
+
+{%- endif %}
+
+{%- if not network.network_manager %}
+
+{# TODO stop/disable/uninstall network manager #}
+
+{%- for interface_name, interface in network.interface.iteritems() %}
+
+{%- if interface.get('managed', True) %}
+
+{%- if grains.os_family in ['RedHat', 'Debian'] %}
+
+{%- if interface.type == 'bridge' and network.bridge == 'openvswitch' %}
+
+linux_interface_{{ interface_name }}:
+ network.managed:
+ - enabled: {{ interface.enabled }}
+ - name: {{ interface_name }}
+ - type: eth
+ {%- if interface.address is defined %}
+ - proto: {{ interface.get('proto', 'static') }}
+ - ipaddr: {{ interface.address }}
+ - netmask: {{ interface.netmask }}
+ {%- else %}
+ - proto: {{ interface.get('proto', 'dhcp') }}
+ {%- endif %}
+ {%- if interface.name_servers is defined %}
+ - dns: {{ interface.name_servers }}
+ {%- endif %}
+ {%- for param in network.interface_params %}
+ {{ set_param(param, interface) }}
+ {%- endfor %}
+ {%- if interface.wireless is defined and grains.os_family == 'Debian' %}
+ {%- if interface.wireless.security == "wpa" %}
+ - wpa-ssid: {{ interface.wireless.essid }}
+ - wpa-psk: {{ interface.wireless.key }}
+ {%- else %}
+ - wireless-ssid: {{ interface.wireless.essid }}
+ - wireless-psk: {{ interface.wireless.key }}
+ {%- endif %}
+ {%- endif %}
+ - require:
+ - pkg: linux_network_bridge_pkgs
+ {%- for network in interface.use_interfaces %}
+ - network: linux_interface_{{ network }}
+ {%- endfor %}
+
+linux_ovs_bridge_{{ interface_name }}:
+ cmd.run:
+ - name: ovs-vsctl add-br {{ interface_name }}
+ - unless: ovs-vsctl show | grep 'Bridge {{ interface_name }}'
+ - require:
+ - network: linux_interface_{{ interface_name }}
+
+{%- for port in interface.use_interfaces %}
+
+linux_ovs_bridge_{{ interface_name }}_port_{{ port }}:
+ cmd.run:
+ - name: ovs-vsctl add-port {{ interface_name }} {{ port }}
+ - unless: ovs-vsctl show | grep 'Interface "{{ interface_name }}"'
+ - require:
+ - cmd: linux_ovs_bridge_{{ interface_name }}
+
+{%- endfor %}
+
+{%- else %}
+
+linux_interface_{{ interface_name }}:
+ network.managed:
+ - enabled: {{ interface.enabled }}
+ - name: {{ interface_name }}
+ - type: {{ interface.type }}
+ {%- if interface.address is defined %}
+ - proto: {{ interface.get('proto', 'static') }}
+ - ipaddr: {{ interface.address }}
+ - netmask: {{ interface.netmask }}
+ {%- else %}
+ - proto: {{ interface.get('proto', 'dhcp') }}
+ {%- endif %}
+ {%- if interface.name_servers is defined %}
+ - dns: {{ interface.name_servers }}
+ {%- endif %}
+ {%- if interface.wireless is defined and grains.os_family == 'Debian' %}
+ {%- if interface.wireless.security == "wpa" %}
+ - wpa-ssid: {{ interface.wireless.essid }}
+ - wpa-psk: {{ interface.wireless.key }}
+ {%- else %}
+ - wireless-ssid: {{ interface.wireless.essid }}
+ - wireless-psk: {{ interface.wireless.key }}
+ {%- endif %}
+ {%- endif %}
+ {%- for param in network.interface_params %}
+ {{ set_param(param, interface) }}
+ {%- endfor %}
+ {%- if interface.type == 'bridge' %}
+ - bridge: {{ interface_name }}
+ - delay: 0
+ - bypassfirewall: True
+ - use:
+ {%- for network in interface.use_interfaces %}
+ - network: {{ network }}
+ {%- endfor %}
+ - ports: {% for network in interface.use_interfaces %}{{ network }} {% endfor %}
+ - require:
+ {%- for network in interface.use_interfaces %}
+ - network: linux_interface_{{ network }}
+ {%- endfor %}
+ {%- endif %}
+
+{%- if interface.gateway is defined %}
+
+linux_system_network:
+ network.system:
+ - enabled: {{ interface.enabled }}
+ - hostname: {{ network.fqdn }}
+ {%- if interface.gateway is defined %}
+ - gateway: {{ interface.gateway }}
+ - gatewaydev: {{ interface_name }}
+ {%- endif %}
+ - nozeroconf: True
+ - nisdomain: {{ system.domain }}
+ - require_reboot: False
+
+{%- endif %}
+
+{%- endif %}
+
+{%- endif %}
+
+{%- if interface.wireless is defined %}
+
+{%- if grains.os_family == 'Arch' %}
+
+linux_network_packages:
+ pkg.installed:
+ - names: {{ network.pkgs }}
+
+/etc/netctl/network_{{ interface.wireless.essid }}:
+ file.managed:
+ - source: salt://linux/files/wireless
+ - mode: 755
+ - template: jinja
+ - require:
+ - pkg: linux_network_packages
+ - defaults:
+ interface_name: {{ interface_name }}
+
+switch_profile_{{ interface.wireless.essid }}:
+ cmd.run:
+ - name: netctl switch-to network_{{ interface.wireless.essid }}
+ - cwd: /root
+ - unless: "iwconfig {{ interface_name }} | grep -e 'ESSID:\"{{ interface.wireless.essid }}\"'"
+ - require:
+ - file: /etc/netctl/network_{{ interface.wireless.essid }}
+
+enable_profile_{{ interface.wireless.essid }}:
+ cmd.run:
+ - name: netctl enable network_{{ interface.wireless.essid }}
+ - cwd: /root
+ - unless: test -e /etc/systemd/system/multi-user.target.wants/netctl@network_{{ interface.wireless.essid }}.service
+ - require:
+ - file: /etc/netctl/network_{{ interface.wireless.essid }}
+
+{%- endif %}
+
+{%- endif %}
+
+{%- endif %}
+
+{%- if interface.route is defined %}
+
+linux_network_{{ interface_name }}_routes:
+ network.routes:
+ - name: {{ interface_name }}
+ - routes:
+ {%- for route_name, route in interface.route.iteritems() %}
+ - name: {{ route_name }}
+ ipaddr: {{ route.address }}
+ netmask: {{ route.netmask }}
+ gateway: {{ route.gateway }}
+ {%- endfor %}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
+
+{%- endif %}
diff --git a/linux/network/proxy.sls b/linux/network/proxy.sls
new file mode 100644
index 0000000..ccfaa9a
--- /dev/null
+++ b/linux/network/proxy.sls
@@ -0,0 +1,25 @@
+{%- from "linux/map.jinja" import network with context %}
+{%- if network.enabled %}
+
+{%- if grains.os_family == 'Debian' %}
+
+{%- if network.proxy.host == 'none' %}
+
+/etc/profile.d/proxy.sh:
+ file.absent
+
+/etc/apt/apt.conf.d/95proxies:
+ file.absent
+
+{%- else %}
+
+/etc/apt/apt.conf.d/95proxies:
+ file.managed:
+ - template: jinja
+ - source: salt://linux/files/95proxies
+
+{%- endif %}
+
+{%- endif %}
+
+{%- endif %}
diff --git a/linux/storage/init.sls b/linux/storage/init.sls
new file mode 100644
index 0000000..f4f90e9
--- /dev/null
+++ b/linux/storage/init.sls
@@ -0,0 +1,13 @@
+{%- from "linux/map.jinja" import storage with context %}
+{%- if storage.mount|length > 0 or storage.swap|length > 0 or storage.multipath %}
+include:
+{%- if storage.mount|length > 0 %}
+- linux.storage.mount
+{%- endif %}
+{%- if storage.swap|length > 0 %}
+- linux.storage.swap
+{%- endif %}
+{%- if storage.multipath %}
+- linux.storage.multipath
+{%- endif %}
+{%- endif %}
diff --git a/linux/storage/mount.sls b/linux/storage/mount.sls
new file mode 100644
index 0000000..038c4ad
--- /dev/null
+++ b/linux/storage/mount.sls
@@ -0,0 +1,26 @@
+{%- from "linux/map.jinja" import storage with context %}
+{%- if storage.enabled %}
+
+{%- for name, mount in storage.mount.iteritems() %}
+
+{%- if mount.enabled %}
+
+mkfs_{{ mount.device}}:
+ cmd.run:
+ - name: "mkfs.{{ mount.file_system }} -L {{ name }} {{ mount.device }}"
+ - onlyif: "test `blkid {{ mount.device }} >/dev/null;echo $?` -eq 2"
+ - require_in:
+ - mount: {{ mount.path }}
+
+{{ mount.path }}:
+ mount.mounted:
+ - device: {{ mount.device }}
+ - fstype: {{ mount.file_system }}
+ - mkmnt: True
+ - opts: {{ mount.get('opts', 'defaults,noatime') }}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
diff --git a/linux/storage/multipath.sls b/linux/storage/multipath.sls
new file mode 100644
index 0000000..ae9151a
--- /dev/null
+++ b/linux/storage/multipath.sls
@@ -0,0 +1,48 @@
+{%- from "linux/map.jinja" import storage with context %}
+{%- if storage.enabled %}
+
+{%- if grains.os_family == 'Debian' %}
+
+linux_multipath_pkgs:
+ pkg.installed:
+ - names: {{ storage.multipath_pkgs }}
+
+{%- if storage.multipath.backend not in ['fujitsu'] %}
+
+linux_multipath_boot_pkg:
+ pkg.installed:
+ - name: multipath-tools-boot
+
+{%- endif %}
+
+{%- if storage.multipath.backend == 'HDS' %}
+
+/etc/multipath.conf:
+ file.managed:
+ - source: salt://linux/files/multipath.conf.hds
+ - template: jinja
+ - require:
+ - pkg: linux_multipath_pkgs
+
+{%- else %}
+
+/etc/multipath.conf:
+ file.managed:
+ - source: salt://linux/files/multipath.conf
+ - template: jinja
+ - require:
+ - pkg: linux_multipath_pkgs
+
+{%- endif %}
+
+multipath_service:
+ service.running:
+ - enable: True
+ - name: multipath-tools
+ - watch:
+ - file: /etc/multipath.conf
+ - sig: multipathd
+
+{%- endif %}
+
+{%- endif %}
diff --git a/linux/storage/swap.sls b/linux/storage/swap.sls
new file mode 100644
index 0000000..81694e9
--- /dev/null
+++ b/linux/storage/swap.sls
@@ -0,0 +1,40 @@
+{%- from "linux/map.jinja" import storage with context %}
+{%- if storage.enabled %}
+
+{%- for swap_name, swap in storage.swap.iteritems() %}
+
+{%- if swap.enabled %}
+
+{%- if swap.engine == 'file' %}
+
+linux_create_swap_file_{{ swap.device }}:
+ cmd.run:
+ - name: 'dd if=/dev/zero of={{ swap.device }} bs=1048576 count={{ swap.size }} && chmod 0600 {{ swap.device }}'
+ - creates: {{ swap.device }}
+
+linux_set_swap_file_{{ swap.device }}:
+ cmd.wait:
+ - name: 'mkswap {{ swap.device }}'
+ - watch:
+ - cmd: linux_create_swap_file_{{ swap.device }}
+
+linux_set_swap_file_status_{{ swap.device }}:
+ cmd.run:
+ - name: 'swapon {{ swap.device }}'
+ - unless: grep {{ swap.device }} /proc/swaps
+ - require:
+ - cmd: linux_set_swap_file_{{ swap.device }}
+
+{{ swap.device }}:
+ mount.swap:
+ - persist: True
+ - require:
+ - cmd: linux_set_swap_file_{{ swap.device }}
+
+{%- endif %}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
diff --git a/linux/system/apparmor.sls b/linux/system/apparmor.sls
new file mode 100644
index 0000000..1aa5109
--- /dev/null
+++ b/linux/system/apparmor.sls
@@ -0,0 +1,28 @@
+{%- from "linux/map.jinja" import system with context %}
+
+include:
+- linux.system.package
+
+{%- if system.apparmor.enabled %}
+
+apparmor_service:
+ service.running:
+ - name: apparmor
+ - enable: true
+ - require:
+ - pkg: linux_packages
+
+{%- else %}
+
+apparmor_service_disable:
+ service.dead:
+ name: apparmor
+ enable: false
+
+apparmor_teardown:
+ cmd.wait:
+ - name: /etc/init.d/apparmor teardown
+ - watch:
+ - service: apparmor_service_disable
+
+{%- endif %}
diff --git a/linux/system/certificate.sls b/linux/system/certificate.sls
new file mode 100644
index 0000000..a342cbe
--- /dev/null
+++ b/linux/system/certificate.sls
@@ -0,0 +1,22 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{%- if system.ca_certificates is defined %}
+
+{%- for certificate in system.ca_certificates %}
+
+{{ system.ca_certs_dir }}/{{ certificate }}.crt:
+ file.managed:
+ - source: salt://pki/{{ certificate }}/{{ certificate }}-chain.cert.pem
+ - watch_in:
+ - cmd: update_certificates
+
+{%- endfor %}
+
+update_certificates:
+ cmd.wait:
+ - name: /usr/sbin/update-ca-certificates
+
+{%- endif %}
+
+{%- endif %}
diff --git a/linux/system/group.sls b/linux/system/group.sls
new file mode 100644
index 0000000..4963829
--- /dev/null
+++ b/linux/system/group.sls
@@ -0,0 +1,28 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{%- for group_name, group in system.group.iteritems() %}
+
+{%- if group.enabled %}
+
+system_group_{{ group_name }}:
+ group.present:
+ - name: {{ group.name }}
+ {%- if group.system is defined and group.system %}
+ - system: True
+ {%- endif %}
+ {%- if group.gid is defined and group.gid %}
+ - gid: {{ group.gid }}
+ {%- endif %}
+
+{%- else %}
+
+system_group_{{ group_name }}:
+ group.absent:
+ - name: {{ group.name }}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
diff --git a/linux/system/init.sls b/linux/system/init.sls
new file mode 100644
index 0000000..b8b3a48
--- /dev/null
+++ b/linux/system/init.sls
@@ -0,0 +1,35 @@
+{%- from "linux/map.jinja" import system with context %}
+include:
+{%- if system.repo|length > 0 %}
+- linux.system.repo
+{%- endif %}
+{%- if system.pkgs|length > 0 %}
+- linux.system.package
+{%- endif %}
+{%- if system.timezone is defined %}
+- linux.system.timezone
+{%- endif %}
+{%- if system.kernel is defined %}
+- linux.system.kernel
+{%- endif %}
+{%- if system.locale is defined %}
+- linux.system.locale
+{%- endif %}
+{%- if system.user|length > 0 %}
+- linux.system.user
+{%- endif %}
+{%- if system.group|length > 0 %}
+- linux.system.group
+{%- endif %}
+{%- if system.job|length > 0 %}
+- linux.system.job
+{%- endif %}
+{%- if grains.os_family == 'RedHat' %}
+- linux.system.selinux
+{%- endif %}
+{%- if system.ca_certificates is defined %}
+- linux.system.certificate
+{%- endif %}
+{%- if system.apparmor is defined %}
+- linux.system.apparmor
+{%- endif %}
diff --git a/linux/system/job.sls b/linux/system/job.sls
new file mode 100644
index 0000000..d589023
--- /dev/null
+++ b/linux/system/job.sls
@@ -0,0 +1,33 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{%- for name, job in system.job.iteritems() %}
+
+linux_job_{{ job.command }}:
+ {%- if job.enabled %}
+ cron.present:
+ - name: {{ job.command }}
+ - user: {{ job.user }}
+ {%- if job.minute is defined %}
+ - minute: '{{ job.minute }}'
+ {%- endif %}
+ {%- if job.hour is defined %}
+ - hour: '{{ job.hour }}'
+ {%- endif %}
+ {%- if job.daymonth is defined %}
+ - daymonth: '{{ job.daymonth }}'
+ {%- endif %}
+ {%- if job.month is defined %}
+ - month: '{{ job.month }}'
+ {%- endif %}
+ {%- if job.dayweek is defined %}
+ - dayweek: '{{ job.dayweek }}'
+ {%- endif %}
+ {%- else %}
+ job.absent:
+ - name: {{ job.command }}
+ {%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/system/kernel.sls b/linux/system/kernel.sls
new file mode 100644
index 0000000..4732e2d
--- /dev/null
+++ b/linux/system/kernel.sls
@@ -0,0 +1,73 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{%- if system.kernel is defined %}
+
+Basic kernel:
+
+ linux:
+ system:
+ kernel:
+ hold: true
+ versions:
+ generic:
+ headers: true
+
+
+ linux:
+ system:
+ kernel:
+ source:
+ engine: pkg
+ repo: from_repo
+ version: 1.13.42
+ hold: true
+ headers: true
+ generic: true
+
+linux-headers-3.13.0-34
+linux-image-3.13.0-34-generic
+linux-headers-3.13.0-34-generic
+
+{%- if system.kernel.get('source', {'engine': 'pkg'}).engine == 'pkg' %}
+
+{%- if system.kernel.version is defined %}
+
+linux_kernel_package:
+ pkg.installed:
+ - name: linux-image-{{ system.kernel.version }}
+ - refresh: true
+
+{%- else %}
+
+linux_kernel_package:
+ pkg.latest:
+ - name: linux-image-generic
+ - refresh: true
+
+{%- endif %}
+
+{%- if system.kernel.headers is defined %}
+{%- if system.kernel.version is defined %}
+
+linux_kernel_package:
+ pkg.installed:
+ - name: linux-image-{{ system.kernel.version }}
+ - version:
+ - refresh: true
+
+{%- else %}
+
+linux_kernel_package:
+ pkg.latest:
+ - name: linux-image-generic
+ - refresh: true
+
+{%- endif %}
+{%- endif %}
+
+{%- endif %}
+
+{%- endif %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/system/locale.sls b/linux/system/locale.sls
new file mode 100644
index 0000000..1b006b5
--- /dev/null
+++ b/linux/system/locale.sls
@@ -0,0 +1,4 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/system/package.sls b/linux/system/package.sls
new file mode 100644
index 0000000..cd9d2cc
--- /dev/null
+++ b/linux/system/package.sls
@@ -0,0 +1,29 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+linux_packages:
+ pkg.installed:
+ - names: {{ system.pkgs }}
+
+{%- for name, package in system.package.iteritems() %}
+
+linux_extra_package_{{ name }}:
+ {%- if package.version == 'latest' %}
+ pkg.latest:
+ {%- else %}
+ pkg.installed:
+ - version: {{ package.version }}
+ {%- endif %}
+ - name: {{ name }}
+ {%- if package.repo is defined %}
+ - fromrepo: {{ package.repo }}
+ {%- endif %}
+ {%- if package.hold is defined %}
+ - hold: {{ package.hold }}
+ {%- endif %}
+ {%- if package.verify is defined %}
+ - skip_verify: {% if package.verify %}false{% else %}true{% endif %}
+ {%- endif %}
+{%- endfor %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/system/repo.sls b/linux/system/repo.sls
new file mode 100644
index 0000000..803ca56
--- /dev/null
+++ b/linux/system/repo.sls
@@ -0,0 +1,98 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{% set default_repos = {} %}
+
+{%- for name, repo in system.repo.iteritems() %}
+
+{%- if grains.os_family == 'Debian' %}
+
+{%- if repo.pin is defined %}
+
+linux_repo_{{ name }}_pin:
+ file.managed:
+ - name: /etc/apt/preferences.d/{{ name }}
+ - source: salt://linux/files/preferences_repo
+ - template: jinja
+ - defaults:
+ repo_name: {{ name }}
+
+{%- else %}
+
+linux_repo_{{ name }}_pin:
+ file.absent:
+ - name: /etc/apt/preferences.d/{{ name }}
+
+{%- endif %}
+
+{%- if repo.get('default', False) %}
+
+{%- do default_repos.update({name: repo}) %}
+
+{%- if repo.key_url %}
+
+linux_repo_{{ name }}_key:
+ cmd.wait:
+ - name: "curl -s {{ repo.key_url }} | apt-key add -"
+ - watch:
+ - file: default_repo_list
+
+{%- endif %}
+
+{%- else %}
+
+linux_repo_{{ name }}:
+ pkgrepo.managed:
+ - human_name: {{ name }}
+ - name: {{ repo.source }}
+ {%- if repo.architectures is defined %}
+ - architectures: {{ repo.architectures }}
+ {%- endif %}
+ - file: /etc/apt/sources.list.d/{{ name }}.list
+ {%- if repo.key_id is defined %}
+ - keyid: {{ repo.key_id }}
+ {%- endif %}
+ {%- if repo.key_server is defined %}
+ - keyserver: {{ repo.key_server }}
+ {%- endif %}
+ {%- if repo.key_url is defined %}
+ - key_url: {{ repo.key_url }}
+ {%- endif %}
+
+{%- endif %}
+
+{%- endif %}
+
+{%- if grains.os_family == "RedHat" %}
+
+{%- if not repo.get('default', False) %}
+
+linux_repo_{{ name }}:
+ pkgrepo.managed:
+ - name: {{ name }}
+ - humanname: {{ name }}
+ - baseurl: {{ repo.source }}
+ - gpgcheck: {% if repo.get('gpgcheck', False) %}1{% else %}0{% endif %}
+
+{%- endif %}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- if default_repos|length > 0 and grains.os_family == 'Debian' %}
+
+default_repo_list:
+ file.managed:
+ - name: /etc/apt/sources.list
+ - source: salt://linux/files/sources.list
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 0644
+ - defaults:
+ default_repos: {{ default_repos }}
+
+{%- endif %}
+
+{%- endif %}
diff --git a/linux/system/selinux.sls b/linux/system/selinux.sls
new file mode 100644
index 0000000..a91ed2e
--- /dev/null
+++ b/linux/system/selinux.sls
@@ -0,0 +1,30 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+include:
+- linux.system.package
+
+{%- if grains.os_family == 'RedHat' %}
+
+{%- if system.selinux == 'disabled' %}
+
+selinux_config:
+ cmd.run:
+ - names:
+ - "sed -i 's/enforcing/disabled/g' /etc/selinux/config; setenforce 0"
+ - "sed -i 's/permissive/disabled/g' /etc/selinux/config; setenforce 0"
+ - unless: cat '/etc/selinux/config' | grep 'SELINUX=disabled'
+
+{%- else %}
+
+selinux_config:
+ selinux.mode:
+ - name: {{ system.get('selinux', 'permissive') }}
+ - require:
+ - pkg: linux_packages
+
+{%- endif %}
+
+{%- endif %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/system/timezone.sls b/linux/system/timezone.sls
new file mode 100644
index 0000000..6b8e778
--- /dev/null
+++ b/linux/system/timezone.sls
@@ -0,0 +1,12 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{%- if system.timezone is defined %}
+
+{{ system.timezone }}:
+ timezone.system:
+ - utc: {{ system.utc }}
+
+{%- endif %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/linux/system/user.sls b/linux/system/user.sls
new file mode 100644
index 0000000..9b5fd9e
--- /dev/null
+++ b/linux/system/user.sls
@@ -0,0 +1,71 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{%- for name, user in system.user.iteritems() %}
+
+{%- if user.enabled %}
+
+system_user_{{ name }}:
+ user.present:
+ - name: {{ name }}
+ - home: {{ user.home }}
+ {%- if user.password is defined %}
+ - password: {{ user.password }}
+ - enforce_password: true
+ - gid_from_name: true
+ {%- endif %}
+ {%- if user.groups is defined %}
+ - groups: {{ user.groups }}
+ {%- endif %}
+ {%- if user.system is defined and user.system %}
+ - system: True
+ {%- else %}
+ - shell: {{ user.get('shell', '/bin/bash') }}
+ {%- endif %}
+ {%- if user.uid is defined and user.uid %}
+ - uid: {{ user.uid }}
+ {%- endif %}
+
+system_user_home_{{ user.home }}:
+ file.directory:
+ - name: {{ user.home }}
+ - user: {{ name }}
+ - mode: 700
+ - makedirs: true
+ - require:
+ - user: system_user_{{ name }}
+
+{%- if user.get('sudo', False) %}
+
+/etc/sudoers.d/90-salt-user-{{ name }}:
+ file.managed:
+ - source: salt://linux/files/sudoer
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 440
+ - defaults:
+ user_name: {{ name }}
+ - require:
+ - user: system_user_{{ name }}
+
+{%- endif %}
+
+{%- else %}
+
+system_user_{{ name }}:
+ user.absent:
+ - name: {{ name }}
+
+system_user_home_{{ user.home }}:
+ file.absent:
+ - name: {{ user.home }}
+
+/etc/sudoers.d/90-salt-user-{{ name }}:
+ file.absent
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
diff --git a/metadata/service/system/init.yml b/metadata/service/system/init.yml
new file mode 100644
index 0000000..d239c14
--- /dev/null
+++ b/metadata/service/system/init.yml
@@ -0,0 +1,19 @@
+applications:
+- linux
+parameters:
+ linux:
+ system:
+ enabled: true
+ user:
+ root:
+ enabled: true
+ name: root
+ home: /root
+ timezone: Europe/Prague
+ cluster: default
+ network:
+ enabled: true
+ hostname: ${linux:system:name}
+ fqdn: ${linux:system:name}.${linux:system:domain}
+ storage:
+ enabled: true