I am trying to build an .sls file which will always restart a service:
systemd-resolved:
service.running:
- restart: True
When deployed, this gives
ID: systemd-resolved
Function: service.running
Result: True
Comment: The service systemd-resolved is already running
Started: 23:46:49.999789
Duration: 53.068 ms
Changes:
This is correct, the service is already running. What I was trying to convey with this command is to restart it. How to do that?
Note: I would like to avoid, if possible, an explicit command to be ran (as I feel it i snot very salt-like - this should rather be handled by the appropriate module):
'systemctl restart systemd-resolved':
cmd.run
If you want your service to reload you need to set reload: True instead.
Beside, If you only want to restart the service if there is any change in any other state, you need to use watch instead.
for instance,
systemd-resolved:
service.running:
- enable: True
- reload: True
- watch:
- pkg: <abc>
Related
I am testing salt as a management system, using ansible so far.
How can I trigger an action (specifically, a service reload) when a state has changed?
In Ansible this is done via notify but browsing salt documentation I cannot find anything similar.
I found watch, which works the other way round: "check something, and if it changed to this and that".
there is also listen which seems to be closer to my needs (the documentation mentions a service reload) but I cannot put together the pieces.
To set an example, how the following scenario would work in salt: check a git repo (= create it if not existing or pull from it otherwise) and if it has changed, reload a service? The Ansible equivalent is
- name: clone my service
git:
clone: yes
dest: /opt/myservice
repo: http://git.example.com/myservice.git
version: master
force: yes
notify:
- restart my service if needed
- name: restart my service if needed
systemd:
name: myservice
state: restarted
enabled: True
daemon_reload: yes
Your example:
ensure my service:
git.latest:
- name: http://git.example.com/myservice.git
- target: /opt/myservice
service.running:
- watch:
- git: http://git.example.com/myservice.git
When there will be change in repo (clone for the first time, update etc.)
the state will be marked as "having changes" thus the dependent states -
service.running in this case - will require changes, for service it means to restart
What you are asking is covered in salt quickstart
Let's assume I have the next simple Ansible playbook:
---
tasks:
- name: Upgrade installed packages
become: true
apt:
upgrade: safe
- name: Install NGINX web server
become: true
apt:
name: nginx
state: latest
notify:
- Restart NGINX
handlers:
- name: Restart NGINX
become: true
service:
name: nginx
state: restarted
As you see, I upgrade installed APT packages first and only then make sure I have the latest Nginx version. The problem is that if there's an update for Nginx, it will be installed in the first task and if so, the second task won't be marked as changed and the handler won't be fired. Is it true? Or Ansible is clever enough to somehow fire this handle only when Nginx was upgraded in the first task?
I wonder about the best practice for this case. Is there a better way than move all the separate installation tasks (which should fire handlers on their change) before the task which upgrades all the installed packages?
Thanks!
This is not "The Ansible way", but it is an option.
one why you can do it is by using lsof to find all the pid's which need restart and pass this information to systemd to get the service name for each pid. And then go over the list of services and restart each one of them.
some one all ready wrote a perl-script like that
- see example here: https://rwmj.wordpress.com/2014/07/10/which-services-need-restarting-after-an-upgrade/
another option is but the same is the restart-services script from the debian-goodies repo/package.
I've recently written a salt state which handles the nginx config for a number of servers from some static variables in pillar. I wanted to roll this out to all the servers, but before I did this I wanted to make sure before the config is applied on a server it has first been tested.
Nginx has an inbuilt configtest which I use frequently on command line, and I found that salt has an nginx module which can be used to run configtest.
I have the following in my state file:
reload-nginx:
service.running:
- enabled: True
- reload: True
- watch:
- pkg: nginx
- file: /etc/nginx/sites-available/*
- file: /etc/nginx/nginx.conf
This should reload nginx if the config files change, or if the nginx install is upgraded/changed. I believe I can run a config test using the following in my state file (untested):
nginx-config-test:
module.run:
- name: nginx.configtest
And I believe if I add this state to the watch in the reload-nginx state it would reload if the configtest passed.
However, I want the reload to happen only if either of the config files have changed AND the config test passes, or if nginx changes AND the configtest passes. I see I can use onlyif to run a state if ALL of the things are True, and from experience you can' have multiple uses of the same method (so I can't have 3 different onlyif's - correct me if I am wrong).
But I don't see any way to reload nginx only if the config files have changed (or nginx has been updated) and the configtest has passed.
Is this possible?
Have the reload state watch the config-test state; have the config-test state watch the config files state and the pkg state. The test will only run if something changes, and the reload will only occur if the test runs and passes.
Caveat: Structurally this will work, but I've never used nginx.configtest, so I can't promise it behaves the way you think.
You will also need to use module.wait rather than module.run; watch statements don't work with .run. Reference here.
So that becomes:
reload-nginx:
service.running:
- name: nginx
- enable: True
- reload: True
- watch:
- module: nginx-config-test
nginx-config-test:
module.wait:
- name: nginx.configtest
- watch:
- file: /etc/nginx/sites-available/*
I'm trying to configure firewalld via saltstack state file (on Centos7). I can add services just fine to permanent configuration, but that indeed goes into 'permanent' configuration, not in the running one. So, either a reload is needed or (less optional) add same services to running configuration too.
What I've used to add the service:
public:
firewalld.present:
- name: public
- services:
- http
That works, but just to permanent.
I've tried to add a "watch", but that won't work at all:
firewalld:
service.running:
- watch:
- file: /etc/firewalld/zones/public.xml
Error is:
Comment: The following requisites were not found:
watch:
file: /etc/firewalld/zones/public.xml
So, what can be done? How can I instruct a service reload via a state file?
You were close. You can't watch a file directly on the file system. You can only watch another Salt state. So your example would look like this:
public:
firewalld.present:
- name: public
- services:
- http
firewalld:
service.running:
- watch:
- firewalld: public
What this means is that the service.running state will look for changes to the firewalld.present state and restart firewalld if changes did occur.
If you want a reload vs a complete restart, this should work:
public:
firewalld.present:
- name: public
- services:
- http
firewalld:
service.running:
- reload: True
- watch:
- firewalld: public
Here's docs on the service state: https://docs.saltstack.com/en/latest/ref/states/all/salt.states.service.html
nginx
pkg.installed:
- name: nginx
service:
- name: nginx
- running
- enable: True
- watch:
- file: /etc/nginx/*
/etc/nginx:
file.recurse:
- source: salt://{{slspath}}/etc/nginx/
- include_empty: True
How can I make the above work?
I want to make it so that every time a new config is added in /etc/nginx/conf.d/newsite.conf nginx is reloaded.
Currently I can only achieve that if I manually add every conf in the sls in the manner:
/etc/nginx/conf.d/newsite.conf:
file.managed:
- source: salt://{{slspath}}/etc/nginx/conf.d/newsite.conf
Is there a way to automate it?
You can't watch a file change within a directory to execute a state. But you can watch a state result to do so. In your case, the following should restart nginx whenever a change is done by the /etc/nginx file state:
nginx
pkg.installed:
- name: nginx
service.running:
- enable: True
- watch:
- file: /etc/nginx
/etc/nginx:
file.recurse:
- source: salt://{{slspath}}/etc/nginx/
- include_empty: True