#ansible #ansible-playbook #ansible-2.x
#ansible #ansible-2.x
Вопрос:
Я новичок в Ansible и пытаюсь изменить строку, /etc/default/grub
чтобы включить аудит.
Мне нужно добавить audit=1
в кавычки где-нибудь в строке, которая выглядит как:
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 rhgb quiet net.ifnames=0"
До сих пор мне удалось удалить строку, и у меня осталось только
net.ifnames=0, audit=1
когда я использую что-то вроде
lineinfile:
state: present
dest: /etc/default/grub
backrefs: yes
regexp: "net.ifnames=0"
line: "1 audit=1"
Можно ли это сделать?
Ответ №1:
Вы можете попробовать это:
- lineinfile:
state: present
dest: /etc/default/grub
backrefs: yes
regexp: '^(GRUB_CMDLINE_LINUX=(?!.* audit)"[^"] )(".*)'
line: '1 audit=12'
Это добавит audit=1
(с начальным пробелом) непосредственно перед закрытием двойных кавычек. Он не будет совпадать без двойных кавычек.
И он пытается быть идемпотентным: не соответствует строкам, которые уже есть audit
(с начальным пробелом) после GRUB_CMDLINE_LINUX=
.
Я бы рекомендовал использовать такие сайты, как regex101, чтобы сначала протестировать ваши регулярные выражения (там также есть режим подстановки).
Когда вы будете удовлетворены результатом, продолжайте выполнение задачи Ansible.
Комментарии:
1. @Джефф Билбро — если вам нужно добавить его только к строкам, имеющим «net.ifnames = 0», вам нужно добавить это в строку регулярного выражения, предоставленную Константином Сурворовым. Вероятно, что-то вроде этого:
regexp: '^(GRUB_CMDLINE_LINUX=.*net.iframes=0.*(?!.*audit)"[^"] )(".*)'
2. Чтобы это также работало, когда GRUB_CMDLINE_LINUX пуст, вы можете использовать
^(GRUB_CMDLINE_LINUX=(?!.*audit)"[^"]*)(".*)
3. Для всех, кто еще попадает сюда с несколько связанным вопросом: в Ubuntu 18.04 я хотел использовать
GRUB_CMDLINE_LINUX_DEFAULT=
вместоGRUB_CMDLINE_LINUX=
, потому что, похоже, это тот, который используется обычно (где все остальные параметры).4. Кто-нибудь может объяснить, почему это разрешает любые символы после второй двойной кавычки? Разве правильная строка не начинается и не заканчивается двойными кавычками (или вообще не содержит двойных кавычек в строке)?
5. может ли эта строка быть добавлена в отдельный файл в
/etc/default/grub.d/
каталоге и иметь тот же эффект?
Ответ №2:
Я хотел убедиться, что для параметра также установлено правильное значение, поэтому я использовал этот вызов замены:
replace:
path: /etc/default/grub
regexp: '^(GRUB_CMDLINE_LINUX=(?:(?![" ]{{ option | regex_escape }}=).)*"?)s*(?:{{ option | regex_escape }}=S s*)?(.*")$'
replace: '1 {{ option }}={{ value }}2'
vars:
option: audit
value: 1
Это работает, если опция не присутствовала ранее, если она была, но имела неправильную опцию (тогда изменяется только значение) и если вся строка была пустой (но тогда добавляется пробел перед опцией). Кроме того, он используется regex_escape
для корректной работы с именами параметров, которые содержат точки и тому подобное, и вам нужно указать их только один раз.
Комментарии:
1. Очень, очень приятно!
2. С регулярным выражением есть одна проблема: если параметр позиционируется как первый после кавычки, например:
GRUB_CMDLINE_LINUX="elevator=noop"
тогда ваше регулярное выражение будет разжевывать начальную кавычку, а результирующая строка заканчивается без первой кавычки, и это нарушает grub. Это исправление:regexp: '^(GRUB_CMDLINE_LINUX="(?:(?!{{ option | regex_escape }}=).)*)([ ]{{ option | regex_escape }}=w [ ])?[ ]?(?:{{ option | regex_escape }}=S )?(.*")$'
и, наконец,replace: '1{{ option }}={{ value }}3'
3. Вы правы, исправили это (хотя и по-другому, поскольку ваш ответ, вероятно, соответствует частичным параметрам, например
ata.elevator
, или что-то в этом роде)