Отладка preseed/late_command для сервера Ubuntu 16.04: тройник не найден из-за несуществующего каталога

Отладка 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, чтобы убедиться, что tee должен быть доступен. Занимаюсь этим уже несколько дней, пересобираю ubuntu раз за разом, только чтобы найти те же ошибки в syslog. Если кто-то может пролить свет на это - это должно быть что-то простое, но я этого не вижу...

решение1

Две вещи:

  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

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 passthrough используется для того, чтобы задавать вопросы debconf с помощью cdebconf в установщике. Это особенно полезно для запуска таких вещей, как dpkg-reconfigure, debconf-apt-progress и tasksel. Утилита log-output используется для регистрации любого вывода; если in-target вызывается с опцией --pass-stdout, log-output будет ее учитывать.

решение2

Похоже, не работает использование echointo 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перед строкой

решение3

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

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

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

  1. простое целевое эхо с простым путем authorized_keys:

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

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

  2. простое внутрицелевое эхо с целевым путем authorized_keys:

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

    создает пустой файл authorized_keys на целевой машине, и при просмотре /var/log/installer/syslogвы видите, что «my string» выводится наstdout

  3. в целевом объекте с явным sh -c...и целевым путем authorized_keys:

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

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

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

решение4

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

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

Обратные кавычки сообщают оболочке, что это нужно выполнить как одну команду.

Связанный контент