Отладка команды 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 ответов
Две вещи:
При выполнении
in-target some_command > /some/path
перенаправление НЕ произойдет внутри цели. Вам нужно будет сделать:in-target --pass-stdout some_command > /target/some/path
В
in-target
команда перенаправит вывод команды в файл журнала. Итак, пытаясь перенаправить вывод изin-target
по умолчанию не работает. Что вам нужно сделать, это использовать--pass-stdout
аргумент в цель
in-target --pass-stdout echo "hello" > /target/root/hello.txt
Это создаст файл /target/root/hello.txt с содержимым hello.
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', но я, вероятно, не ищу правильное место.
обычный in-target echo с простым путём авторизованным ключом:
in-target echo "my string" >> /home/username/.ssh/authorized_keys;
дает "каталог не найден" в
/var/log/installer/syslog
обычный in-target echo с целевым путем author_keys путем:
in-target echo "my string" >> /target/home/username/.ssh/authorized_keys;
создает пустой файл author_keys на целевой машине и при просмотре
/var/log/installer/syslog
вы обнаружите, что "моя строка" выводится наstdout
в цели с явным
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;