LINUX.ORG.RU

Добавление секции non-free в APT через Ansible - почему удаляются строки?

 , , ,


0

1

Имеется исходный файл /etc/apt/sources.list :

deb http://ftp.ru.debian.org/debian bullseye main contrib
deb-src http://ftp.ru.debian.org/debian bullseye main contrib

deb http://security.debian.org/debian-security bullseye-security main contrib
deb-src http://security.debian.org/debian-security bullseye-security main contrib
И надо в него добавить секцию non-free.

Придумал такой код:
   - name: "Добавление секции non-free в APT"                                                                              
     replace:                                                                                                              
       dest: /etc/apt/sources.list                                                                                         
       regexp: '(deb|deb-src)\s*(http://.*debian.*)\s*(.?)\s*main contrib\s.*(?!non-free)'                                 
       replace: '\1 \2 \3 main contrib non-free'
В результате в файле, за каким-то хреном, исчезают строки deb-src:
deb http://ftp.ru.debian.org/debian bullseye   main contrib non-free

deb http://security.debian.org/debian-security bullseye-security   main contrib non-free

Почему так то? Какое правильное регулярное выражение должно быть?

★★★★★

Ответ на: комментарий от einhander

Проблема в том, что секции одного и того же репозитария не должны подключаться в разных файлах. Конечно, формально можно это сделать, можно и штаны через голову надевать.

Задача поставлена предельно простая: «Ко всем строкам с дебиановкими репозитариями в файле sources.list добавить секцию non-free». Все.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Проблема в том, что секции одного и того же репозитария не должны подключаться в разных файлах.

Это где-то написано? А то я встречал другое мнение у дистрописателей на основе дебиана.

einhander ★★★★★
()
Ответ на: комментарий от Xintrea

Так ты же ансиблом управляешь составом каталога source.list.d, какие могут быть после этого вопросы. Либо ты добавил, либо ты не добавил нужные компоненты через ансибл.

Я так и делал когда, мне надо было.

einhander ★★★★★
()
Ответ на: комментарий от George

Видимо, все пропустили истинную причину проблемы, а я ее написал. Вот еще раз пишу:

В общем получается такая вещь (тут до матчинга non-free еще дело не дошло, проблема возникает раньше). Итак.

Если использовать выражение:

^(deb|deb-src)\s+(http:\/\/[^\s]*debian[^\s]*)\s+(.+?)\s+main\s+contrib.*$

То оно матчится правильно. Оно находит в моем случае четыре строки, в них находит три группы, все правильно высчитывает. Вот ссылка на распиндальку: https://regex101.com/r/3wiwUs/1

Теперь, если взять, и после contrib всунуть \s* вот так:
^(deb|deb-src)\s+(http:\/\/[^\s]*debian[^\s]*)\s+(.+?)\s+main\s+contrib\s*.*$

То происходит следующая вещь. Этот \s* попадает на перевод строки. Матчит его (считает перевод строки за \s), и захватывает через .*$ всю последующую строку. Поэтому каждая вторая строка и пропадает.

Я такого вообще не ожидал, я думал что если есть $, на нем всегда будет останавливаться парсинг строки. А тут вона как - перепрыгивает на следующую. Пока не знаю что с этим делать.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от s-warus

во родил строки где есть ".debian." заканчивающиеся на " main.*$" менять на '\1 main contrib non-free'

Вот тебе пример:

deb http://security.debian.org/debian-security bullseye-security main contrib

Где ты здесь увидел ".debian."?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

'(^.*\.debian\..*) main.*$'

расшифровываю
^ начало строки
.* какие угодно сим. кроме \n
\.debian\. ".debian."
.* какие угодно сим. кроме \n
main.*$ до " main"любые символы до конца строки

s-warus ★★★
()
Ответ на: комментарий от Xintrea

тогда стары вариант:

- name: "Добавление секции non-free в APT"                                                                              
     replace:                                                                                                              
       dest: /etc/apt/sources.list                                                                                         
       regexp: ' main.*$'                                 
       replace: ' main contrib non-free'
всё начинающиеся ' main' до конца строки менять на ' main contrib non-free'

Я думал, что:

Задача поставлена предельно простая: «Ко всем строкам с дебиановкими репозитариями в файле sources.list добавить секцию non-free». Все.

поэтому добавил проверку на .debian.

s-warus ★★★
()
Последнее исправление: s-warus (всего исправлений: 1)

В общем, да, проблема была в том, что «\s» матчит все пробельные символы, включая перевод строки.

Вместо этого простого символа надо писать так:

\s(?<!\n) - любой пробельный символ, кроме перевода строки

Взято отсюда: https://stackoverflow.com/questions/35838690/escaping-n-in-s-match-in-reg-ex-...

И тогда все начинает работать правильно.

Полный код выглядит так:

  - name: "Добавление секции non-free в APT"
    replace:
      dest: /etc/apt/sources.list
      regexp: '^(deb|deb-src)\s+(https?:\/\/[^\s]*debian[^\s]*)\s+(.+?)\s+main\s+contrib(\s(?<!\n))*(?!non-free)(\s(?<!\n))*$'
      replace: '\1 \2 \3 main contrib non-free'


Ограничения этого кода в том, что он находит только строки с main+contrib, и заменяет их на main+contrib+non-free. Причем не дает повторять non-free, если запустить заново.

Как сделать так, чтобы просто проверялось наличие non-free в списке секций (независимо от того, какие секции уже прописаны) и добавлялось non-free если таковой секции нет, я не придумал. Можно было бы написать собственный фильтр, но это уже за гранью, я устал.

Xintrea ★★★★★
() автор топика
Последнее исправление: Xintrea (всего исправлений: 1)
Ответ на: комментарий от Xintrea

порадовало https? впервые увидел, ни где не встречал

\/\/ это можно было не экранировать (оставить //) это для sed да и там чаще умолчальный разделитель другой назначают.

проблему понял

 - name: "Добавление секции non-free в APT"
    replace:
      dest: /etc/apt/sources.list
      regexp: '^(deb|deb-src)\s+(https?://[^\s]+)\s+([^\s]+)\s+(.*(?!non-free)(\s(?<!\n))*)$'
      replace: '\1 \2 \3 \4 non-free'
не уверен, но где то так

s-warus ★★★
()
Ответ на: комментарий от s-warus

Да, этот вариант тоже неплох, по сути он добавляет в конец deb-строки non-free, если на конце строки такового нет.

Но тут нет проверки на принадлежность репы к debian.

Xintrea ★★★★★
() автор топика

надо в него добавить секцию non-free

Ты занимаешься фигнёй.

Удали /etc/apt/sources.list, вместо него создавай отдельные .conf файлы в /etc/apt/sources.list.d/. Хоть по файлу для каждого раздела. Включение-выключение репозиториев и их разделов превратится в тривиальное создание-удаление файлов. Или переименование, если вдруг нужно часто включать-выключать.

i-rinat ★★★★★
()