Add 'debops.sysnews' Ansible role

parent 8335151b
......@@ -1193,6 +1193,14 @@ stages:
JANE_LOG_PATTERN: '\[debops\.sysfs\]'
tags: [ 'shell', 'vagrant-vm' ]
'sysnews role':
<<: *test_role_no_deps
JANE_TEST_PLAY: '${DEBOPS_PLAYBOOKS}/service/sysnews.yml'
JANE_INVENTORY_GROUPS: 'debops_service_sysnews'
JANE_DIFF_PATTERN: '.*/debops.sysnews/.*'
JANE_LOG_PATTERN: '\[debops\.sysnews\]'
# --- t --- [[[2
......@@ -44,6 +44,8 @@ Added
- :ref:`debops.prosody`: configure an xmpp server on a given host
- :ref:`debops.sysnews`: manage System News bulletin for UNIX accounts
- You can now :ref:`use Vagrant <quick_start__vagrant>` to create an Ansible
Controller based on Debian Stretch and use it to manage itself or other hosts
over the network.
- name: Manage System News entries
hosts: [ 'debops_service_sysnews' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
- role: debops.sysnews
tags: [ 'role::sysnews' ]
- include: sysnews.yml
- include: sysfs.yml
- include: swapfile.yml
\ No newline at end of file
debops.sysnews - Manage System News using Ansible
Copyright (C) 2018 Maciej Delmanowski <>
Copyright (C) 2018 DebOps
This Ansible role is part of DebOps.
DebOps is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3, as
published by the Free Software Foundation.
DebOps is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DebOps. If not, see
# .. vim: foldmarker=[[[,]]]:foldmethod=marker
# debops.sysnews default variables
# ================================
# .. contents:: Sections
# :local:
# APT packages [[[
# ----------------
# .. envvar:: sysnews__base_packages [[[
# List of the default APT packages to install for System News support.
sysnews__base_packages: [ 'sysnews' ]
# ]]]
# .. envvar:: sysnews__packages [[[
# List of additional APT packages to install for System News support.
sysnews__packages: []
# ]]]
# ]]]
# News notification [[[
# ---------------------
# .. envvar:: sysnews__notification [[[
# Enable or disable notification about unread News items after login.
sysnews__notification: True
# ]]]
# .. envvar:: sysnews__notification_min_uid [[[
# Specify the minimum UID number for an UNIX account to see the notification.
# This is done so that the news notification does not show up after switching
# to the ``root`` account via :command:`su` or :command:`sudo`.
sysnews__notification_min_uid: '900'
# ]]]
# .. envvar:: sysnews__notification_max_uid [[[
# Specify the maximum UID number for an UNIX account to see the notification.
# This might be useful if you want to limit the System News to only for the
# system administrators in a multi-person team.
# The value usually would be ``999`` for non-clustered hosts where normal users
# start at ``1000``, and ``9999`` for clustered hosts where users in the LDAP
# database might start at ``10000``. By default, all users will see the
# notification.
sysnews__notification_max_uid: ''
# ]]]
# .. envvar:: sysnews__notification_command [[[
# The shell command executed to display System News notification after login.
sysnews__notification_command: '/usr/bin/news -l -n'
# ]]]
# ]]]
# Misc configuration [[[
# ----------------------
# .. envvar:: sysnews__group [[[
# Name of the UNIX system group which grants write access to the
# :file:`/var/lib/sysnews/` directory. This group is defined in the
# :command:`sysnews` Debian package and preferably shouldn't be changed.
sysnews__group: 'staff'
# ]]]
# .. envvar:: sysnews__entry_contact [[[
# The string used as the contact information for the host administrators,
# inserted in one of the default System News entries if set.
sysnews__entry_contact: '{{
if (ansible_local|d() and ansible_local.machine|d() and|d())
else "" }}'
# ]]]
# ]]]
# System News static entries [[[
# ------------------------------
# These variables define configuration of the System News entries which will
# not expire automatically. See :ref:`sysnews__ref_entries` for more details.
# .. envvar:: sysnews__default_entries [[[
# List of default System News entries defined by the role.
- name: 'Welcome to System News'
content: |
This host has support for the "System News" bulletin, which can be read
using the 'news' command.
Members of the '{{ sysnews__group }}' UNIX system group can create news entries in the form
of text files located in the '/var/lib/sysnews/' directory. The news items
will automatically expire after a month, unless they are specifically
marked for no expiration.
Read the news(1) manpage for more details.
state: 'present'
- name: 'This machine is managed using Ansible'
content: |
Ansible is a Configuration Management tool used to configure hosts in an
automated fashion.
Any changes in files which are managed using Ansible may be unexpectedly
lost if not accounted for by the system administrator. These files can be
recognized by a special annotation near the top of the file which informs
that this file is managed remotely.
{% if sysnews__entry_contact|d() %}
If you want to perform system modifications on this host, consider
contacting the system administrators first. They can be reached using
{{ sysnews__entry_contact }}
{% endif %}
state: 'present'
# ]]]
# .. envvar:: sysnews__entries [[[
# List of System News entries which should be present on all hosts in the
# Ansible inventory.
sysnews__entries: []
# ]]]
# .. envvar:: sysnews__group_entries [[[
# List of System News entries which should be present on hosts in a specific
# Ansible inventory group.
sysnews__group_entries: []
# ]]]
# .. envvar:: sysnews__host_entries [[[
# List of System News entries which should be present on specific hosts in the
# Ansible inventory.
sysnews__host_entries: []
# ]]]
# .. envvar:: sysnews__combined_entries [[[
# This list combines all of the other System News entry lists and passes them
# to the role tasks.
sysnews__combined_entries: '{{ sysnews__default_entries
+ sysnews__entries
+ sysnews__group_entries
+ sysnews__host_entries }}'
# ]]]
# ]]]
- role: debops.ansible_plugins
author: 'Maciej Delmanowski'
description: 'Manage local machine information and MOTD'
company: 'DebOps'
license: 'GPL-3.0'
min_ansible_version: '2.4.0'
- name: Ubuntu
- precise
- trusty
- xenial
- name: Debian
- wheezy
- jessie
- stretch
- system
- motd
- issue
- login
- name: Install packages required for System News
name: '{{ item }}'
state: 'present'
- '{{ sysnews__base_packages }}'
- '{{ sysnews__packages }}'
- name: Disable System News notification after login
path: '/etc/profile.d/'
state: 'absent'
when: not sysnews__notification|bool
- name: Configure System News notification after login
src: 'etc/profile.d/'
dest: '/etc/profile.d/'
owner: 'root'
group: 'root'
mode: '0644'
when: sysnews__notification|bool
- name: Remove persistent news files
path: '/var/lib/sysnews/{{ }}'
state: 'absent'
with_items: '{{ sysnews__combined_entries | parse_kv_items }}'
when:|d() and item.state|d('present') == 'absent'
- name: Generate persistent news files
src: '{{ item.src | d(omit) }}'
content: '{{ item.content | d(omit) }}'
dest: '/var/lib/sysnews/{{ }}'
owner: 'root'
group: 'root'
mode: '0644'
with_items: '{{ sysnews__combined_entries | parse_kv_items }}'
when:|d() and item.state|d('present') != 'absent'
- name: Update list of persistent news files
content: |
{% for entry in sysnews__combined_entries | parse_kv_items %}
{{ }}
{% endfor %}
dest: '/var/lib/sysnews/.noexpire'
create: True
owner: 'root'
group: '{{ sysnews__group }}'
mode: '0664'
- name: Make sure that Ansible local facts directory exists
path: '/etc/ansible/facts.d'
state: 'directory'
owner: 'root'
group: 'root'
mode: '0755'
- name: Save System News local facts
src: 'etc/ansible/facts.d/sysnews.fact.j2'
dest: '/etc/ansible/facts.d/sysnews.fact'
owner: 'root'
group: 'root'
mode: '0755'
register: sysnews__register_facts
- name: Update Ansible facts if they were modified
action: setup
when: sysnews__register_facts|changed
#!/usr/bin/env python
# {{ ansible_managed }}
from __future__ import print_function
from json import dumps
from sys import exit
output = {'installed': True}
print(dumps(output, sort_keys=True, indent=4))
# {{ ansible_managed }}
# Print System News notification after login
SYSNEWS_MIN_UID="{{ sysnews__notification_min_uid }}"
SYSNEWS_MAX_UID="{{ sysnews__notification_max_uid }}"
SYSNEWS_COMMAND="{{ sysnews__notification_command }}"
# Check if sysnews is installed
type /usr/bin/news > /dev/null 2>&1 || return 0
# Make sure that shell is bash or zsh
[ -n "$BASH_VERSION" -o -n "$ZSH_VERSION" ] || return 0
# Make sure that it's interactive session
[[ $- == *i* ]] || return 0
# Show news only to selected users
if [ "${EUID}" -ge "${SYSNEWS_MIN_UID}" ] ; then
if [ -n "${SYSNEWS_MAX_UID}" ] ; then
if [ "${EUID}" -le "${SYSNEWS_MAX_UID}" ] ; then
tty -s && eval "${SYSNEWS_COMMAND}"
tty -s && eval "${SYSNEWS_COMMAND}"
......@@ -250,6 +250,7 @@ System configuration
- :ref:`debops.swapfile`
- :ref:`debops.sysctl`
- :ref:`debops.sysfs`
- :ref:`debops.sysnews`
- :ref:`debops.users`
- ``debops.console``
- ``debops.gitusers``
Default variable details
Some of the ``debops.sysnews`` default variables have more extensive
configuration than simple strings or lists, here you can find documentation and
examples for them.
.. contents::
:depth: 1
.. _sysnews__ref_entries:
The ``sysnews__*_entries`` lists can be used to add or manage permanent
System News entries in the :file:`/var/lib/sysnews/` directory. The variables
are combined in the order specified by the :envvar:`sysnews__combined_entries`
variable, entries with the same name are combined together; the entries later
in the list override parameters from previous entry with the same name.
Each list entry is a YAML dictionary with specific parameters:
Required. Name of the text file located in the :file:`/var/lib/sysnews/`
directory (spaces if the filename are permitted).
Optional, conflicts with ``content``. Path to a text file located on the
Ansible Controller, which should be put in the :file:`/var/lib/sysnews/`
directory with a given name. By default the path is relative to the
:file:`files/` directory of the ``debops.sysnews`` Ansible role.
Optional, conflicts with ``src``. YAML text block which contains a text to
put in a file in the :file:`/var/lib/sysnews/` directory with a given name.
The text can contain Jinja templating which will be evaluated at Ansible
execution time.
Optional. Define the state of a particular news file. If multiple list
entries define a file state, the last one wins. Recognized states:
- not specified or ``present``: the file will be put in the
:file:`/var/lib/sysnews/` directory.
- ``absent``: the specified file will be removed.
- ``ignore``: the given configuration entry will be ignored by the role. This
can be used to conditionally activate or skip entries.
Add a new, permanent System News entry:
.. code-block:: yaml
- name: 'News about an application'
content: |
A new application has been installed and is ready to be used.
Have a nice day.
state: 'present'
Getting started
.. contents::
How to add news manually
The System News entries added by this role using ``sysnews__*_entries``
variables are permanent, ie. they will not expire automatically after a month.
System administrators can add more temporary news entries by putting text files
in the :file:`/var/lib/sysnews/` directory, with the filename being the title
of a news item. This directory is owned by the ``staff`` UNIX system group, and
any users in this group can also add entries in that directory. Custom news
entries will be automatically removed after a month.
To make temporary news items permanent, you can edit the
:file:`/var/lib/sysnews/.noexpire` file. Put names of the custom files to
retain outside of the ``ANSIBLE MANAGED BLOCK`` section, this way your custom
changes will be preserved during the next Ansible run of this role.
Example inventory
The ``debops.sysnews`` role can be enabled on a host when it's added to
a particular Ansible inventory group:
.. code-block:: none
Example playbook
If you are using this role without DebOps, here's an example Ansible playbook
that uses the ``debops.sysnews`` role:
.. literalinclude:: ../../../../ansible/playbooks/service/sysnews.yml
:language: yaml
.. _debops.sysnews:
This role can be used to manage "System News" bulletin displayed after users
log in to a particular host using local system console or SSH. System News can
be used to notify users about important changes on the host; this is especially
useful in multi-user environments or on bastion hosts.
The System News can be read by executing the :command:`news` command in the
shell. You can read all of the news entries by executing the :command:`news -a`
.. toctree::
:maxdepth: 2
.. literalinclude:: ../../../../ansible/roles/debops.sysnews/COPYRIGHT
Local Variables:
mode: rst
ispell-local-dictionary: "american"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment