Add role to install nfs-server, cleanup roles and configuration

- use generic media_dirs including vdr recdir, loop over them to
  create directories, configure samba, nfs, etc.
- add role to install an configure nfs-kernel-server
- cleanup roles
- add custom fact modules
This commit is contained in:
Alexander Grothe 2017-03-13 10:40:35 +01:00
parent d6647e1613
commit 10c3d12215
16 changed files with 385 additions and 81 deletions

View File

@ -32,7 +32,7 @@ The ~yavdr07.yml~ playbook sets up a fully-featured yaVDR installation:
- yavdr-network # enable network client capabilities
- samba-install # install samba server
- samba-config # configure samba server
#- nfs-server # install nfs server
- nfs-server # install nfs server
#- nfs-config # configure nfs server
- yavdr-xorg # graphical session
- yavdr-remote # remote configuration files, services and scripts
@ -40,7 +40,7 @@ The ~yavdr07.yml~ playbook sets up a fully-featured yaVDR installation:
- autoinstall-satip # install vdr-plugin-satip if a Sat>IP server has been found
- autoinstall-targavfd
- autoinstall-imonlcd
- template-test
#- template-test
handlers:
- include: handlers/main.yml
@ -106,15 +106,6 @@ drivers:
sundtek: auto
ddvb-dkms: auto
#+END_SRC
** Media directories
#+BEGIN_SRC yaml :tangle group_vars/all :mkdirp yes
# dictionary of directories for (shared) files. Automatically exported via NFS and Samba if those roles are enabled
media_dirs:
audio: /srv/audio
video: /srv/audio
pictures: /srv/audio
files: /srv/files
#+END_SRC
** VDR user, directories, special configuration and plugins
#+BEGIN_SRC yaml :tangle group_vars/all :mkdirp yes
# properties of the user vdr and vdr-related options
@ -126,7 +117,7 @@ vdr:
home: /var/lib/vdr
recdir: /srv/vdr/video
hide_first_recording_level: false
safe_dirnames: true
safe_dirnames: true # escape characters (useful for windows clients and FAT/NTFS file systems)
override_vdr_charset: false
# add the vdr plugins you want to install
@ -137,10 +128,27 @@ vdr_plugins:
- vdr-plugin-softhddevice
#+END_SRC
** Media directories
#+BEGIN_SRC yaml :tangle group_vars/all :mkdirp yes
# dictionary of directories for (shared) files. Automatically exported via NFS and Samba if those roles are enabled
media_dirs:
audio: /srv/audio
video: /srv/audio
pictures: /srv/picture
files: /srv/files
backups: /srv/backups
recordings: '{{ vdr.recdir }}'
#+END_SRC
** NFS
#+BEGIN_SRC yaml :tangle group_vars/all :mkdirp yes
nfs:
insecure: false # required for OS X clients and when using libnfs as unprivileged user (e.g. KODI)
#+END_SRC
** Samba
#+BEGIN_SRC yaml :tangle group_vars/all :mkdirp yes
samba:
workgroup: YAVDR
windows_compatible: '{{ vdr.safe_dirnames }}' # disable unix extensions, enable follow symlinks and wide links
#+END_SRC
** Additional packages
#+BEGIN_SRC yaml :tangle group_vars/all :mkdirp yes
@ -155,9 +163,9 @@ extra_packages:
#+BEGIN_SRC yaml :tangle group_vars/all :mkdirp yes
#system:
# shutdown: poweroff
# grub:
# timeout: 0
# boot_options: quiet nosplash
grub:
timeout: 0
boot_options: quiet nosplash
#+END_SRC
* Roles
** yavdr-common
@ -228,7 +236,6 @@ yavdr-common executes the following tasks:
# file: roles/yavdr-common/tasks/main.yml
#+END_SRC
***** Disable default installation of recommended packages
This task prevents apt to automatically install all recommended dependencies for packages:
#+BEGIN_SRC yaml :tangle roles/yavdr-common/tasks/main.yml :mkdirp yes
- name: apt | prevent automatic installation of recommended packages
@ -255,7 +262,7 @@ yavdr-common executes the following tasks:
regexp: '^(Prompt=).*$'
line: '\1never'
#+END_SRC
***** Setting up the package repositories
***** Set up package repositories
#+BEGIN_SRC yaml :tangle roles/yavdr-common/tasks/main.yml :mkdirp yes
- name: add yaVDR PPAs
apt_repository:
@ -269,7 +276,7 @@ yavdr-common executes the following tasks:
upgrade: dist
update_cache: yes
#+END_SRC
***** Installing essential packages
***** Install essential packages
#+BEGIN_SRC yaml :tangle roles/yavdr-common/tasks/main.yml :mkdirp yes
- name: apt | install basic packages
apt:
@ -295,7 +302,28 @@ yavdr-common executes the following tasks:
- xfsprogs
#+END_SRC
***** run local fact scripts
***** Install additional packages (user defined)
#+BEGIN_SRC yaml :tangle roles/yavdr-common/tasks/main.yml
- name: apt | install extra packages
apt:
name: '{{ item }}'
state: present
install_recommends: no
with_items:
'{{ extra_packages }}'
#+END_SRC
***** create media directories
#+BEGIN_SRC yaml :tangle roles/yavdr-common/tasks/main.yml
- name: create media directories
file:
dest: '{{ item.value }}'
owner: '{{ vdr.user }}'
group: '{{ vdr.group }}'
state: directory
mode: '0777'
with_dict: '{{ media_dirs }}'
#+END_SRC
***** Gather facts with custom modules
#+BEGIN_SRC yaml :tangle roles/yavdr-common/tasks/main.yml :mkdirp yes
- name: get information about usb and pci hardware and loaded kernel modules
hardware_facts:
@ -324,7 +352,7 @@ yavdr-common executes the following tasks:
verbosity: 1
#+END_SRC
*** templates
#+BEGIN_SRC shell :tangle roles/yavdr-common/templates/90-norecommends.j2 :mkdirp yes
#+BEGIN_SRC c :tangle roles/yavdr-common/templates/90-norecommends.j2 :mkdirp yes
{{ ansible_managed_file | comment('c') }}
// Recommends are as of now still abused in many packages
APT::Install-Recommends "0";
@ -402,22 +430,6 @@ The additional plugins to install can be set in the variable ~{{vdr_plugins}}~ i
with_items:
'{{ vdr_plugins | default({}) }}'
#+END_SRC
*** Set up the directories for files in /srv
#+BEGIN_SRC yaml :tangle roles/vdr/tasks/main.yml :mkdirp yes
- name: create directories for media files
file:
state: directory
owner: '{{ vdr.user }}'
group: '{{ vdr.group }}'
mode: 0777
dest: '{{ item }}'
with_items:
- /srv/videos
- /srv/music
- /srv/picture
- /srv/backups
#+END_SRC
** STARTED yavdr-network
*** default variables
@ -574,6 +586,32 @@ systemctl --user import-environment
enabled: yes
state: started
#+END_SRC
** nfs-server
*** tasks
#+BEGIN_SRC yaml :tangle roles/nfs-server/tasks/main.yml :mkdirp yes
- name: install nfs server packages
apt:
name: '{{ item }}'
state: present
install_recommends: no
with_items:
- nfs-kernel-server
- nfs-common
- name: create /etc/exports
template:
src: templates/nfs-exports.j2
dest: /etc/exports
notify: [ 'Restart NFS Kernel Server' ]
#+END_SRC
*** templates
#+BEGIN_SRC conf :tangle roles/nfs-server/templates/nfs-exports.j2 :mkdirp yes
/srv *(rw,fsid=0,sync,no_subtree_check,all_squash,anongid={{ vdr.gid }},anonuid={{ vdr.uid }})
{% for name, path in media_dirs.iteritems() %}
{{ path }} *(rw,fsid={{ loop.index }},sync,no_subtree_check,all_squash,anongid={{ vdr.gid }},anonuid={{ vdr.uid }}{{ ',insecure' if nfs.insecure else '' }})
{% endfor %}
#+END_SRC
** nfs-config
** samba-install
*** tasks
#+BEGIN_SRC yaml :tangle roles/samba-install/tasks/main.yml :mkdirp yes
@ -599,7 +637,7 @@ systemctl --user import-environment
# TODO:
#- name: divert original smbd.conf
- name: create smb.conf.custom
- name: touch smb.conf.custom
file:
state: touch
dest: '/etc/samba/smb.conf.custom'
@ -613,6 +651,8 @@ systemctl --user import-environment
notify: [ 'Restart Samba' ]
#+END_SRC
*** templates
**** smb.conf
***** global settings
#+BEGIN_SRC yaml :tangle roles/samba-config/templates/smb.conf.j2 :mkdirp yes
# {{ ansible_managed_file }}
@ -687,11 +727,19 @@ systemctl --user import-environment
# to anonymous connections
map to guest = bad user
{% if samba.windows_compatible %}
# disable unix extensions and enable following symlinks
unix extensions = no
follow symlinks= yes
wide links= yes
{% endif %}
#+END_SRC
***** media directories
#+BEGIN_SRC yaml :tangle roles/samba-config/templates/smb.conf.j2 :mkdirp yes
{% for name, path in media_dirs.iteritems() %}
[{{ name }}]
path = {{ path }}
comment = {{ name }} on %h
browseable = yes
guest ok = yes
writeable = yes
browseable = yes
@ -703,7 +751,9 @@ systemctl --user import-environment
wide links = yes
{% endfor %}
#+END_SRC
***** include custom samba exports
#+BEGIN_SRC yaml :tangle roles/samba-config/templates/smb.conf.j2 :mkdirp yes
include = /etc/samba/smb.conf.custom
#+END_SRC
** grub-config
@ -711,7 +761,7 @@ include = /etc/samba/smb.conf.custom
#+BEGIN_SRC yaml :tangle roles/grub-config/defaults/main.yml :mkdirp yes
system:
shutdown: poweroff
grub:
grub:
timeout: 0
boot_options: quiet nosplash
#+END_SRC
@ -730,7 +780,7 @@ system:
dest: /etc/default/grub
state: present
regexp: '^(GRUB_CMDLINE_LINUX_DEFAULT=")'
line: '\1{{ system.grub.boot_options}}"'
line: '\1{{ grub.boot_options}}"'
backrefs: yes
notify: [ 'Update GRUB' ]
#+END_SRC
@ -748,9 +798,9 @@ menuentry "PowerOff" {
{% endif %}
if [ "${recordfail}" = 1 ]; then
set timeout={{ 3 if system.grub.timeout < 3 else system.grub.timeout }}
set timeout={{ 3 if grub.timeout < 3 else grub.timeout }}
else
set timeout={{ system.grub.timeout if system.grub.timeout is defined else 0 }}
set timeout={{ grub.timeout if grub.timeout is defined else 0 }}
fi
#+END_SRC
*** handlers
@ -996,7 +1046,19 @@ Section "Screen"
{% endif %}
EndSubSection
{% if system.x11.display.0.default or system.x11.default %}
# Option "ConnectedMonitor" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?><?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
{% if system.x11.display.0.device is definded and system.x11.display.0.device %}
Option "ConnectedMonitor" {{ system.x11.display.0.device }}
{% else %}
Option "ConnectedMonitor" {{ system.x11.default }}
{% endif %}
# Option "ConnectedMonitor" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?><?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
#Option "ConnectedMonitor"
"<?cs if:(?system.x11.display.0.device) ?>
<?cs call:fix_display_name(system.x11.display.0.device) ?>
<?cs else ?>
<?cs var:system.x11.default ?>
<?cs /if ?>
<?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
# Option "UseDisplayDevice" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?>"
# <?cs /if ?>
# <?cs if:(?system.hardware.nvidia.0.edid && system.hardware.nvidia.0.edid == "1") ?>
@ -1277,4 +1339,11 @@ if __name__ == '__main__':
#masked: no
register: samba_reload
- name: Restart NFS Kernel Server
systemd:
name: nfs-server.service
state: restarted
enabled: yes
#masked: no
register: nfs_reload
#+END_SRC

View File

@ -17,13 +17,6 @@ drivers:
sundtek: auto
ddvb-dkms: auto
# dictionary of directories for (shared) files. Automatically exported via NFS and Samba if those roles are enabled
media_dirs:
audio: /srv/audio
video: /srv/audio
pictures: /srv/audio
files: /srv/files
# properties of the user vdr and vdr-related options
vdr:
user: vdr
@ -33,7 +26,7 @@ vdr:
home: /var/lib/vdr
recdir: /srv/vdr/video
hide_first_recording_level: false
safe_dirnames: true
safe_dirnames: true # escape characters (useful for windows clients and FAT/NTFS file systems)
override_vdr_charset: false
# add the vdr plugins you want to install
@ -43,8 +36,21 @@ vdr_plugins:
- vdr-plugin-restfulapi
- vdr-plugin-softhddevice
# dictionary of directories for (shared) files. Automatically exported via NFS and Samba if those roles are enabled
media_dirs:
audio: /srv/audio
video: /srv/audio
pictures: /srv/picture
files: /srv/files
backups: /srv/backups
recordings: '{{ vdr.recdir }}'
nfs:
insecure: false # required for OS X clients and when using libnfs as unprivileged user (e.g. KODI)
samba:
workgroup: YAVDR
windows_compatible: '{{ vdr.safe_dirnames }}' # disable unix extensions, enable follow symlinks and wide links
# additional packages you want to install
extra_packages:
@ -53,8 +59,8 @@ extra_packages:
- w-scan
- bpython3
system:
shutdown: poweroff
grub:
#system:
# shutdown: poweroff
grub:
timeout: 0
boot_options: quiet nosplash

View File

@ -5,3 +5,11 @@
enabled: yes
#masked: no
register: samba_reload
- name: Restart NFS Kernel Server
systemd:
name: nfs-server.service
state: restarted
enabled: yes
#masked: no
register: nfs_reload

126
library/hardware_facts.py Normal file
View File

@ -0,0 +1,126 @@
#!/usr/bin/env python
# This Module collects the vendor- and device ids for USB- and PCI(e)-devices and currently loaded kernel modules.
DOCUMENTATION = '''
---
module: hardware_facts
short_description: collects facts for kernel modules, usb and pci devices
description:
- This Module collects the vendor- and device ids for USB- and PCI(e)-devices and
currently loaded kernel modules.
options:
usb:
required: False
default: True
description:
- return a list of vendor- and device ids for usb devices in '04x:04x' notation
pci:
required: False
default: True
description:
- return a list of vendor- and device ids for pci devices in '04x:04x' notation
modules:
required: False
default: True
description:
- return a list of currently loaded kernel modules
gpus:
required: False
default: True
description:
- return a list of devices of the pci gpu class (0x030000)
notes:
- requres python-pyusb and python-kmodpy
requirements: [ ]
author: "Alexander Grothe <seahawk1986@gmx.de>"
'''
EXAMPLES = '''
- name: get information about usb and pci hardware and loaded kernel modules
hardware_facts:
usb: True
pci: True
modules: True
- debug:
var: usb
- debug
var: pci
- debug
var: modules
- debug
var: gpus
'''
import glob
import json
import os
import sys
import usb.core
from collections import namedtuple
import kmodpy
from ansible.module_utils.basic import *
PCIDevice = namedtuple("PCIDevice", ['idVendor', 'idProduct', 'idClass'])
def get_pci_devices():
for device in glob.glob('/sys/devices/pci*/*:*:*/'):
with open(os.path.join(device, 'device')) as d:
product_id = int(d.read().strip(), 16)
with open(os.path.join(device, 'vendor')) as d:
vendor_id = int(d.read().strip(), 16)
with open(os.path.join(device, 'class')) as d:
class_id = int(d.read().strip(), 16)
yield PCIDevice(idVendor=vendor_id, idProduct=product_id, idClass=class_id)
def format_device_list(iterator):
return ["{:04x}:{:04x}".format(d.idVendor, d.idProduct) for d in iterator]
def format_gpu_device_list(iterator):
def get_entries(iterator):
for d in iterator:
if d.idClass == 0x030000:
yield ("{:04x}:{:04x}".format(d.idVendor, d.idProduct))
return [entry for entry in get_entries(iterator)]
arg_specs = {
'usb': dict(default=True, type='bool', required=False),
'pci': dict(default=True, type='bool', required=False),
'modules': dict(default=True, type='bool', required=False),
'gpus': dict(default=True, type='bool', required=False),
}
def main():
module = AnsibleModule(argument_spec=arg_specs, supports_check_mode=True,)
collect_usb = module.params['usb']
collect_pci = module.params['pci']
collect_modules = module.params['modules']
collect_gpus = module.params['gpus']
if collect_usb:
usb_devices = format_device_list(usb.core.find(find_all=True))
else:
usb_device = []
if collect_pci:
pci_devices = format_device_list(get_pci_devices())
else:
pci_devices = []
if collect_modules:
k = kmodpy.Kmod()
modules = [m[0] for m in k.loaded()]
else:
modules = []
if collect_gpus:
gpus = format_gpu_device_list(get_pci_devices())
else:
gpus = []
data = {'usb': usb_devices, 'pci': pci_devices, 'modules': modules, 'gpus': gpus}
module.exit_json(changed=False, ansible_facts=data, msg=data)
if __name__ == '__main__':
main()

63
library/satip_facts.py Normal file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env python2
DOCUMENTATION = '''
---
module: hardware_facts
short_description: "check if at least one SAT>IP server responds on the network"
description:
- This script sends a multicast message and awaits responses by Sat>IP servers.
Returns the boolean variable 'satip_detected'
'''
EXAMPLES = '''
- name: "detect SAT>IP Server on the network"
action: satip_facts
- debug:
var: satip_detected
'''
import json
import socket
import sys
import time
from ansible.module_utils.basic import *
SSDP_ADDR = "239.255.255.250"
SSDP_PORT = 1900
# SSDP_MX = max delay for server response
# a value of 2s is recommended by the SAT>IP specification 1.2.2
SSDP_MX = 2
SSDP_ST = "urn:ses-com:device:SatIPServer:1"
ssdpRequest = "\r\n".join((
"M-SEARCH * HTTP/1.1",
"HOST: %s:%d" % (SSDP_ADDR, SSDP_PORT),
"MAN: \"ssdp:discover\"",
"MX: %d" % (SSDP_MX),
"ST: %s" % (SSDP_ST),
"\r\n"))
def main():
module = AnsibleModule(argument_spec={}, supports_check_mode=True,)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# according to Sat>IP Specification 1.2.2, p. 20
# a client should send three requests within 100 ms with a ttl of 2
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
sock.settimeout(SSDP_MX + 0.5)
for _ in range(3):
sock.sendto(ssdpRequest, (SSDP_ADDR, SSDP_PORT))
time.sleep(0.03)
try:
response = sock.recv(1000)
if response and "SERVER:" in response:
got_response = True
else:
raise ValueError('No satip server detected')
except (socket.timeout, ValueError):
got_response = False
module.exit_json(changed=False, ansible_facts={'satip_detected': got_response})
if __name__ == '__main__':
main()

View File

@ -1,5 +1,5 @@
system:
shutdown: poweroff
grub:
grub:
timeout: 0
boot_options: quiet nosplash

View File

@ -11,6 +11,6 @@
dest: /etc/default/grub
state: present
regexp: '^(GRUB_CMDLINE_LINUX_DEFAULT=")'
line: '\1{{ system.grub.boot_options}}"'
line: '\1{{ grub.boot_options}}"'
backrefs: yes
notify: [ 'Update GRUB' ]

View File

@ -10,7 +10,7 @@ menuentry "PowerOff" {
{% endif %}
if [ "${recordfail}" = 1 ]; then
set timeout={{ 3 if system.grub.timeout < 3 else system.grub.timeout }}
set timeout={{ 3 if grub.timeout < 3 else grub.timeout }}
else
set timeout={{ system.grub.timeout if system.grub.timeout is defined else 0 }}
set timeout={{ grub.timeout if grub.timeout is defined else 0 }}
fi

View File

@ -0,0 +1,14 @@
- name: install nfs server packages
apt:
name: '{{ item }}'
state: present
install_recommends: no
with_items:
- nfs-kernel-server
- nfs-common
- name: create /etc/exports
template:
src: templates/nfs-exports.j2
dest: /etc/exports
notify: [ 'Restart NFS Kernel Server' ]

View File

@ -0,0 +1,4 @@
/srv *(rw,fsid=0,sync,no_subtree_check,all_squash,anongid={{ vdr.gid }},anonuid={{ vdr.uid }})
{% for name, path in media_dirs.iteritems() %}
{{ path }} *(rw,fsid={{ loop.index }},sync,no_subtree_check,all_squash,anongid={{ vdr.gid }},anonuid={{ vdr.uid }}{{ ',insecure' if nfs.insecure else '' }})
{% endfor %}

View File

@ -0,0 +1,3 @@
samba:
workgroup: YAVDR
windows_compatible: true # disable unix extensions, enable follow symlinks and wide links

View File

@ -3,7 +3,7 @@
# TODO:
#- name: divert original smbd.conf
- name: create smb.conf.custom
- name: touch smb.conf.custom
file:
state: touch
dest: '/etc/samba/smb.conf.custom'

View File

@ -71,11 +71,17 @@
# to anonymous connections
map to guest = bad user
{% if samba.windows_compatible %}
# disable unix extensions and enable following symlinks
unix extensions = no
follow symlinks= yes
wide links= yes
{% endif %}
{% for name, path in media_dirs.iteritems() %}
[{{ name }}]
path = {{ path }}
comment = {{ name }} on %h
browseable = yes
guest ok = yes
writeable = yes
browseable = yes

View File

@ -58,16 +58,3 @@
install_recommends: no
with_items:
'{{ vdr_plugins | default({}) }}'
- name: create directories for media files
file:
state: directory
owner: '{{ vdr.user }}'
group: '{{ vdr.group }}'
mode: 0777
dest: '{{ item }}'
with_items:
- /srv/videos
- /srv/music
- /srv/picture
- /srv/backups

View File

@ -56,6 +56,23 @@
- usbutils
- xfsprogs
- name: apt | install extra packages
apt:
name: '{{ item }}'
state: present
install_recommends: no
with_items:
'{{ extra_packages }}'
- name: create media directories
file:
dest: '{{ item.value }}'
owner: '{{ vdr.user }}'
group: '{{ vdr.group }}'
state: directory
mode: '0777'
with_dict: '{{ media_dirs }}'
- name: get information about usb and pci hardware and loaded kernel modules
hardware_facts:
usb: True

View File

@ -11,7 +11,7 @@
- yavdr-network # enable network client capabilities
- samba-install # install samba server
- samba-config # configure samba server
#- nfs-server # install nfs server
- nfs-server # install nfs server
#- nfs-config # configure nfs server
- yavdr-xorg # graphical session
- yavdr-remote # remote configuration files, services and scripts
@ -19,6 +19,7 @@
- autoinstall-satip # install vdr-plugin-satip if a Sat>IP server has been found
- autoinstall-targavfd
- autoinstall-imonlcd
#- template-test
handlers:
- include: handlers/main.yml