You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe
Commands like systemctl stop abc* support glob-style wildcards.
However, systemd.service() does not.
Describe the solution you'd like
The obvious "user space" solution is probably something like this:
fromfnmatchimportfnmatchfrompyinfraimporthostfrompyinfra.facts.systemdimportSystemdEnabledfrompyinfra.operationsimportsystemddefservices(pattern, name=None, **kwargs):
""" Manage the state of all systemd services matching a glob pattern """services=get_enabled_services()
forserviceinservices:
iffnmatch(service, pattern):
iname=NoneifnameisNoneelsef"{name}: {service}"systemd.service(
name=iname,
service=service,
**kwargs
)
defget_enabled_services():
""" Return a list of enabled systemd services """units=host.get_fact(SystemdEnabled)
return [nameforname, enabledinunits.items() ifenabledandname.endswith(".service")]
However, this works through the list of services step by step, which means it accumulates the run time. Doing the same operation via the systemctl command will perform all changes in parallel and needs only approximately the longest run time of any of the changes.
Reading the underlying code, it turns out that this basically already works. The smallest possible change that resolves the issue would be the following:
In pyinfra/pyinfra/operations/util/service.py replace line 19
I.e., if any of the services that match the pattern is running, treat the pattern as running. This is compatible with the current non-wildcard name behavior since fnmatch matches non-wildcard strings to themselves.
The question is whether this is enough or if it is wished that the list of services that is interacted with is shown in the printed output. This would need a much bigger change, I fear.
Either way, I would be happy to provide a PR for the above solution (plus the needed docs changes, etc.) or work on a more complex solution as I would really like this feature to exist.
The text was updated successfully, but these errors were encountered:
Thinking about this further, there is a chance for a performance impact for the non-wildcard case if there are many services -- simply because matching every item in a large dict is worse than a single lookup in the dict. To mitigate this:
So, only if the lookup fails find the matches. If there is no match at all, stay with is_running=None (this was potentially wrong in the simpler solution above). If there are matches, use any() to get the overall state of the pattern matches.
evoldstad
added a commit
to evoldstad/pyinfra
that referenced
this issue
Sep 23, 2024
Is your feature request related to a problem? Please describe
Commands like
systemctl stop abc*
support glob-style wildcards.However,
systemd.service()
does not.Describe the solution you'd like
The obvious "user space" solution is probably something like this:
However, this works through the list of services step by step, which means it accumulates the run time. Doing the same operation via the
systemctl
command will perform all changes in parallel and needs only approximately the longest run time of any of the changes.Reading the underlying code, it turns out that this basically already works. The smallest possible change that resolves the issue would be the following:
In
pyinfra/pyinfra/operations/util/service.py
replace line 19with
I.e., if any of the services that match the pattern is running, treat the pattern as running. This is compatible with the current non-wildcard name behavior since fnmatch matches non-wildcard strings to themselves.
The question is whether this is enough or if it is wished that the list of services that is interacted with is shown in the printed output. This would need a much bigger change, I fear.
Either way, I would be happy to provide a PR for the above solution (plus the needed docs changes, etc.) or work on a more complex solution as I would really like this feature to exist.
The text was updated successfully, but these errors were encountered: