LinuxForum.Fans
Тема

Скрипты для работы с Mageia в chroot

Автор: xxblx 11 сообщений 3739 просмотров
13.11.2014 04:33 · отредактировано #400691

Доброго времени суток.

Скрипты Mageia-chroot предназначены для автоматизации процесса использования Mageia в chroot.

На данный момент имеются:

  • mageia-chroot.tarball - скрипт генерирует *.tar.gz с Mageia, содержащий минимальный набор пакетов: basesystem-minimal, urpmi и rpm-build, для использования в chroot. При использовании скрипта можно указать произвольный каталог для chroot (по умолчанию /mnt/chroot), используемое зеркало репозитория, произвольный .rpmmacros и каталог, куда будет помещен созданный тарболл (по умолчанию $PWD).
  • mageia-chroot.rpmbuild - скрипт собирает rpm-пакеты из src.rpm. Процесс сборки полностью автоматизирован, нужно только указать тарболл с Mageia и src.rpm (можно указывать несколько). При использовании можно указать произвольный .rpmmacros, дополнительный репозиторий, который требуется при сборке (для установки каких-то buildrequires из стороннего репозитория, например), произвольный каталог, куда будет складываться готовые rpm'ы (по умолчанию $PWD).
  • mageia-chroot.install - скрипт устанавливает Mageia в chroot. По умолчанию устанавливается минимальный набор пакетов: basesystem-minimal и urpmi, но пользовать указать дополнительные пакеты для установки. При использовании скрипта можно указать произвольный каталог для chroot (по умолчанию /mnt/chroot) и используемое зеркало репозитория.
  • mageia-chroot.unpack - скрипт распаковывает Mageia из тарболла для использования в chroot.
  • mageia-chroot.run - скрипт выполняет непосредственно операцию chroot. Система может быть запущена из каталога (т.е. уже установленная / распакованная), либо из тарболла (будет автоматически распакована и запущена). Пользователь может либо указать скрипт, который будет выполнен в chroot, после чего из chroot будет совершен выход, либо самостоятельно в интерактивном режиме использовать систему в chroot.

В TODO:

  • mageia-choot.xlaunch - скрипт для запуска графических приложений в chroot

Git-репозиторий на bitbucket: https://bitbucket.org/xxblx/mageia-chroot
Там в вики проекта для скриптов имеются отдельные страницы со справками и примерами. Так же можно на форуме MRC посмотреть.

Буду рад услышать критику по поводу этих скриптов, т.к. в баше я не силен и наверняка где-нибудь да напортачил.

14.11.2014 18:37 #400849

Добавил в mageia-chroot.rpmbuild обработку INT сигнала. Чтобы в случае нажатия Ctrl + C, процесс завершался не абы как, а сначала чтобы отмонтировало <chroot>/dev и <chroot>/proc, удалило созданные скриптом файлы и лишь затем завершало работу скрипта.

20.11.2014 02:27 #401764

Добавил скрипты install (установка в Mageia в chroot), unpack распаковывает Mageia из тарболла для использования в chroot и run (непосредственно chroot, можно запускать уже распакованную систему, можно запускать систему из тарболла, можно просто выполнить chroot и дальше управлять самостоятельно, а можно указать скрипт, который будет выполнен в chroot, после чего из chroot будет выполнен выход).

20.11.2014 04:26 #401765
"xxblx" написал:
Буду рад услышать критику по поводу этих скриптов
text
CHPATH=$OPTARG;

1. $OPTARG неплохо было-бы в кавычки заключить, в "такие".
2. точка с запятой не нужна

text
if [ -f "${CHPATH}" ]; then
·   echo "Error. PATH must be a directiry, not a file!"

тут надо писать так:

text
if  [ !  -d  "$CHPATH" ]

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

text
ROOT_DIRS=`/usr/bin/ls /`
USR_DIRS=`/usr/bin/ls /usr`

for d in $ROOT_DIRS

сложно. Проще будет как-то так:

text
for d in /*
text
echo "Error. PATH cannot be in / or in /usr"

и для этого нужен цикл(даже два)? Разве нельзя сделать как-то так:

text
if  grep -qE  '^/(usr)?' < <(echo "$ACHPATH")

?

text
if [ ! -d "${CHPATH}" ]; then
·   mkdir -p "${CHPATH}"
fi

условие не нужно. Просто пишите

text
 mkdir -p "${CHPATH}"
text
# Exit
exit 0

вдвойне ненужно. Даже вредно, т.к. при ошибке будет код "SUCCESS".

PS: я-бы на bash писал.

"xxblx" написал:
т.к. в баше я не силен

а вы и не на bash пишите, а пытаетесь на POSIX shell. Зачем? Сложно жеж!

20.11.2014 18:43 · отредактировано #401833
"drBatty" написал:
1. $OPTARG неплохо было-бы в кавычки заключить, в "такие".
2. точка с запятой не нужна

Поправлю.

"drBatty" написал:
тут надо писать так:
if [ ! -d "$CHPATH" ]
а то ведь кроме регулярных файлов и каталогов есть и другие файлы, к примеру блочные устройства.

Да, я об этом как-то и не подумал даже.

"drBatty" написал:
ROOT_DIRS=`/usr/bin/ls /`
USR_DIRS=`/usr/bin/ls /usr`
for d in $ROOT_DIRS

сложно. Проще будет как-то так:
for d in /*
echo "Error. PATH cannot be in / or in /usr"

и для этого нужен цикл(даже два)? Разве нельзя сделать как-то так:
if grep -qE '^/(usr)?' < <(echo "$ACHPATH")
?

Ну да, перемудрил я здесь. На самом деле можно сделать проще и короче.

"drBatty" написал:
if [ ! -d "${CHPATH}" ]; then
· mkdir -p "${CHPATH}"
fi
условие не нужно. Просто пишите
mkdir -p "${CHPATH}"

Понял. Поправлю.

"drBatty" написал:
# Exit
exit 0
вдвойне ненужно. Даже вредно, т.к. при ошибке будет код "SUCCESS".

Т.е. просто exit оставить без кода возврата? Или вообще убрать?

И сразу возникает еще вопрос. А вот в таких местах, как это (из mageia-chroot.rpmbuild, 155 - 159 строки)

text
# Check archive
if [ ! -f "${TGZ}" ]; then
    echo "Error: ${TGZ} doesn't exist"
    exit 1
fi

Тут проверяет есть ли указанный тарболл, если нет - ошибка. Тут exit 1 стоит на своем месте?
Я так понял, что 0 - успех, 1 и выше - коды ошибок, и т.к. если утилиты сами по себе коды возвращают в случае ошибок, то при if fi надо самому в случае чего указать, что с ошибкой завершение было. Или я ошибаюсь?

"drBatty" написал:
а вы и не на bash пишите, а пытаетесь на POSIX shell. Зачем? Сложно жеж!

Вы про ?

text
#!/bin/sh

В Mageia
[console][xxblx@localhost ~]$ file /bin/sh
/bin/sh: symbolic link to `bash'[/console]
Или все равно лучше на #!/bin/bash заменить?

drBatty, большое спасибо за замечания! Опыта у меня нет, по этому местами вот такие ляпы есть по незнанию.

21.11.2014 04:16 #401870
"xxblx" написал:
Т.е. просто exit оставить без кода возврата? Или вообще убрать?

просто exit/return выдаёт код предыдущий команды. Exit/return с параметром нужен для выхода/возврата с другим кодом, например если "ошибка" это "не ошибка" и наоборот. Или если "ошибка", но скрипт/функция хочет отметить особую ситуацию, с которой справится не в состоянии самостоятельно(и тем не менее, справится с этим можно, не фатально). Тогда она может вернуть скажем код 64.

В данном случае можно вообще убрать.

"xxblx" написал:
Тут проверяет есть ли указанный тарболл, если нет - ошибка. Тут exit 1 стоит на своем месте?
да. Потому что вам надо echo выполнить, а оно обычно выполняется успешно.
"xxblx" написал:
Я так понял, что 0 - успех, 1 и выше - коды ошибок, и т.к. если утилиты сами по себе коды возвращают в случае ошибок, то при if fi надо самому в случае чего указать, что с ошибкой завершение было. Или я ошибаюсь?
всё правильно:
0 — успех
1..63 — ошибка во внешней утилите (смотреть в man для подробностей)
64..126 — внутренняя ошибка, я обычно такие коды в своих скриптах/функциях использую
128..255 — прервано сигналом.

"xxblx" написал:
Или все равно лучше на #!/bin/bash заменить?

да, потому что во первых bash'а может не быть, во вторых bash в таком виде работает "в режиме совместимости", т.е. если конструкция допустима и в bash, и в POSIX shell, то она выполняется как в POSIX, а если она с POSIX не определена, то как в bash (т.е. башизмы работают, но только если ничего подобного нет в POSIX), в третьих лучше с первой строки знать, что это bash(администратору).

"xxblx" написал:
Опыта у меня нет, по этому местами вот такие ляпы есть по незнанию.

всё у вас хорошо, это мелкие ошибки, и даже может и не ошибки. Грубых _ошибок_ у вас нет.

21.11.2014 11:25 #401908

drBatty, понял. Спасибо большое!
Ближайшее время все поправлю и залью обновленные скрипты в гит-репозиторий.

24.11.2014 21:51 #402354
"drBatty" написал:
ROOT_DIRS=`/usr/bin/ls /`
USR_DIRS=`/usr/bin/ls /usr`

for d in $ROOT_DIRS

сложно. Проще будет как-то так:

for d in /*

echo "Error. PATH cannot be in / or in /usr"

и для этого нужен цикл(даже два)? Разве нельзя сделать как-то так:

if grep -qE '^/(usr)?' < <(echo "$ACHPATH")

?

Вот думаю сейчас над этим. Пока что в голову пришло только одно решение

Заменить

text
# CHROOT must be a dir located NOT in / and NOT in /usr
if [ ! -d "${CHPATH}" ]; then
    echo "Error. PATH must be a directiry!"
    exit 1
fi

ACPATH=`readlink -e "${CHPATH}"` # make absolute path if [ "${ACPATH}" = "/" ]; then echo "Error. PATH cannot be /" exit 1 fi

ROOT_DIRS=`/usr/bin/ls /` USR_DIRS=`/usr/bin/ls /usr`

for d in $ROOT_DIRS do if [ "/${d}" = "${ACHPATH}" ]; then echo "Error. PATH cannot be in / or in /usr" exit 1 fi done

for d in $USR_DIRS do if [ "/usr/${d}" = "${ACHPATH}" ]; then echo "Error. PATH cannot be in / or in /usr" exit 1 fi done

На

text
# CHROOT must be a dir located NOT in / and NOT in /usr
if [ ! -d "${CHPATH}" ]; then
    echo "Error. PATH must be a directiry!"
    exit 1
fi

ACPATH=`readlink -e "${CHPATH}"` # make absolute path if [ "${ACPATH}" = "/" ]; then echo "Error. PATH cannot be /" exit 1 fi

CHECK_PATH=`grep -oP "^/(?(?=usr).*/.+/.+$|.*/.+$)" <(echo "${ACPATH}")` if [ -z CHECK_PATH ]; then echo "Error. PATH cannot be in / or in /usr" exit 1 fi

Конструкция

text
grep -oP "^/(?(?=usr).*/.+/.+$|.*/.+$)" <(echo "${ACPATH}")

найдет только те пути, которые не на 1-ом уровне / или /usr. То есть найдет /etc/chroot, но не найдет /etc, найдет /usr/share/dir, но не найдет /usr/share и т.д.

Но мне почему-то кажется, что я опять усложняю. Ткните, пожалуйста, носом, если опять не вижу очевидного.

25.11.2014 00:53 #402371

"xxblx" написал:
grep -oP "^/(?(?=usr).*/.+/.+$|.*/.+$)
а без PCRE не обойтись, да?
text
grep -E '^/(usr/)?[^/]+$'

не?

25.11.2014 01:10 #402372
"drBatty" написал:
а без PCRE не обойтись, да?
text
grep -E '^/(usr/)?[^/]+$'

не?

Ну, как я сейчас вижу из приведенной вами команды, прекрасно можно и без PCRE. И выглядит ваш вариант понятно и аккуратно.
Спасибо.

03.12.2014 05:28 #403700

"xxblx" написал:
И выглядит ваш вариант понятно и аккуратно.
понятность и акуратность это бонус. А основная фича — надёжность и быстродействие, которое обеспечивается тем, что обычные RE работают за один проход. Это обычное дело например в пхп-быдлокодинге, когда напишут PCRE тип вашей, а потом плачут: "какой тормозной и жручий пхп". А дело-то совсем и не в пхп, а в привычке писать write only быдлокод.

Регулярки это тоже ЯП, хотя и не тьюринг-полный.
Войдите или зарегистрируйтесь, чтобы ответить.