Отладка команды preseed/late_command для сервера Ubuntu 16.04: не найден или отсутствует каталог

Я пытаюсь запустить следующий preseed-файл на сервере Ubuntu 16.04 (во время сборки упаковщика):

d-i preseed/late_command string \
in-target mkdir -v -p -m 0440 "/etc/sudoers.d"; \
in-target echo "%vagrant ALL=(ALL) NOPASSWD: ALL" | tee -a /etc/sudoers.d/vagrant; \
in-target echo "Defaults:vagrant !requiretty" | tee -a /etc/sudoers.d/vagrant; \
in-target chmod 440 /etc/sudoers.d/vagrant;

В /var/log/installer/syslog я вижу следующую ошибку:

log-output: sh:
log-output: tee: not found

Когда я изменяю часть "| tee -a" на ">>" примерно так:

d-i preseed/late_command string \
in-target mkdir -v -p -m 0440 "/etc/sudoers.d"; \
in-target echo "%vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant; \
in-target echo "Defaults:vagrant !requiretty" >> /etc/sudoers.d/vagrant; \
in-target chmod 440 /etc/sudoers.d/vagrant;

Внезапно он начинает жаловаться, что не может найти каталог, не говоря ничего о строке mkdir - поэтому он не создает каталог и не находит его:

log-output: sh: can't create /etc/sudoers.d/vagrant: nonexistent directory
log-output: sh: can't create /etc/sudoers.d/vagrant: nonexistent directory
log-output: chmod:
log-output: cannot access '/etc/sudoers.d/vagrant'
log-output: : No such file or directory

Я изучал другие скрипты на github. Также я добавил следующую строку в файл preseed.cfg:

d-i pkgsel/include string openssh-server coreutils wget sudo

Я даже пытался установить coreutils как команду in-target, чтобы убедиться, что она должна быть доступна. Обдумайте это в течение нескольких дней, перестраивая Ubuntu раз за разом, только чтобы найти те же ошибки в системном журнале. Если бы кто-то мог пролить свет на это - это должно быть что-то простое, но я не вижу этого...

6 ответов

Две вещи:

  1. При выполнении in-target some_command > /some/pathперенаправление НЕ произойдет внутри цели. Вам нужно будет сделать: in-target --pass-stdout some_command > /target/some/path

  2. В in-targetкоманда перенаправит вывод команды в файл журнала. Итак, пытаясь перенаправить вывод из in-targetпо умолчанию не работает. Что вам нужно сделать, это использовать --pass-stdout аргумент в цель

in-target --pass-stdout echo "hello" > /target/root/hello.txt

Это создаст файл /target/root/hello.txt с содержимым hello.

Источник: https://salsa.debian.org/installer-team/debian-installer-utils/-/blob/3e67bc7987eb4a9cdff5fe8d1084e612fe7bb48f/README

in-target: запускает указанную команду в / target и возвращает ее статус выхода. Сквозной интерфейс debconf используется для того, чтобы вопросы debconf задавались с помощью cdebconf в установщике. Это особенно полезно для запуска таких вещей, как dpkg-reconfigure, debconf-apt-progress и tasksel. Утилита log-output используется для регистрации любого вывода; если in-target вызывается с параметром --pass-stdout, вывод журнала будет учитывать это.

Это не похоже на работу, чтобы использовать echo в in-target, Чтобы решить эту проблему, попробуйте следующее (пробовал в Ubuntu 18.04):

d-i preseed/late_command string \
    echo "some text" >> /target/path/to/file.ext ; \
    in-target [some-other-command-in-target]

НОТА:

  • Не использовать in-target до линии
  • использование /target перед реальным путем
  • В других командах вы можете в основном использовать in-target до линии

Если вы предпочитаете использовать установщик Debian, это сработало для меня на сервере 17.10.1 при добавлении открытого ключа ssh к авторизованному ключу. Вы должны убедиться, что каталог.ssh создан заранее.

d-i preseed/late_command string in-target /bin/sh -c 'echo "my string" >> /home/username/.ssh/authorized_keys';

Я потратил около одного дня на отладку этого и попробовал следующее с различными результатами. Было бы неплохо, если бы была более подробная документация о том, какая оболочка используется в установщике Debian для различных директив не / 'in-target', но я, вероятно, не ищу правильное место.

  1. обычный in-target echo с простым путём авторизованным ключом:

    in-target echo "my string" >> /home/username/.ssh/authorized_keys;
    

    дает "каталог не найден" в /var/log/installer/syslog

  2. обычный in-target echo с целевым путем author_keys путем:

    in-target echo "my string" >> /target/home/username/.ssh/authorized_keys;
    

    создает пустой файл author_keys на целевой машине и при просмотре /var/log/installer/syslog вы обнаружите, что "моя строка" выводится на stdout

  3. в цели с явным sh -c... и целевой путь author_keys:

    in-target /bin/sh -c 'echo "my string" >> /target/home/username/.ssh/authorized_keys';
    

    выдает ошибку "каталог не найден" в /var/log/installer/syslog

Надеюсь, это сэкономит немного времени и отладки!

Вы можете использовать Ubiquity вместо Debian-Installer ( https://wiki.ubuntu.com/Installer/FAQ), поэтому ваша команда будет такой:

ubiquity  ubiquity/success_command string \
 in-target /bin/mkdir -v -p -m 0440 "/target/etc/sudoers.d"; \
 in-target /bin/echo "%vagrant ALL=(ALL) NOPASSWD: ALL" >> /target/etc/sudoers.d/vagrant; \
 in-target /bin/echo "Defaults:vagrant !requiretty" >> /target/etc/sudoers.d/vagrant; \
 in-target /bin/chmod 440 /target/etc/sudoers.d/vagrant

Он решает вопрос "нет такого файла или каталога", указав в нужном месте: /target/etc/

Echo будет работать в директиве in-target. Вы должны поставить это с обратными галочками (`). Например, я хотел обновить имя хоста моей машины из файла preseed:

целевое имя хоста echo "ubn"$(lshw | grep -m 1 serial | awk '{print tolower ($2)}')

Back-ticks говорит оболочке выполнить это как одну команду.

Оригинальная попытка использованияteeтакже будет работать, если вы просто переместитеin-targetкоманда в нужное место...

      d-i preseed/late_command string \
in-target mkdir -v -p -m 0440 "/etc/sudoers.d"; \
echo "%vagrant ALL=(ALL) NOPASSWD: ALL" | in-target tee -a /etc/sudoers.d/vagrant; \
echo "Defaults:vagrant !requiretty" | in-target tee -a /etc/sudoers.d/vagrant; \
in-target chmod 440 /etc/sudoers.d/vagrant;
Другие вопросы по тегам