1 (20.11.2014 02:33:45 отредактировано xxblx)

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

Скрипты 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 посмотреть.

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

Fedora GNOME3

2

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

Fedora GNOME3

3

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

Fedora GNOME3

4

xxblx пишет:

Буду рад услышать критику по поводу этих скриптов

CHPATH=$OPTARG;

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

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

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

if  [ !  -d  "$CHPATH" ]

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

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")

?

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

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

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

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

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

xxblx пишет:

т.к. в баше я не силен

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

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

5 (20.11.2014 18:44:42 отредактировано xxblx)

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 строки)

# 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. Зачем? Сложно  жеж!

Вы про ?

#!/bin/sh

В Mageia

 Консоль:
[xxblx@localhost ~]$ file /bin/sh
/bin/sh: symbolic link to `bash'

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

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

Fedora GNOME3

6

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 пишет:

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

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

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

7

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

Fedora GNOME3

8

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")

?

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

Заменить

# 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

На

# 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

Конструкция

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

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

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

Fedora GNOME3

9

xxblx пишет:

grep -oP "^/(?(?=usr).*/.+/.+$|.*/.+$)

а без PCRE не  обойтись, да?

grep -E '^/(usr/)?[^/]+$'

не?

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

10

drBatty пишет:

а без PCRE не  обойтись, да?

grep -E '^/(usr/)?[^/]+$'

не?

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

Fedora GNOME3

11

xxblx пишет:

И выглядит ваш вариант понятно и аккуратно.

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

Регулярки  это тоже ЯП,  хотя и не тьюринг-полный.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)