Причины неудобств
Каждый раз для подключения к самбе надо изрядно потыкать мышкой: Finder -> Подключение к серверу -> ввод имени сервера (-> первый раз ещё и пароль спросят) -> выбор папок, которые нужно подключить -> Ok. Потом, если захочется делать бэкап в примонтированную по самбе директорию, прийдётся ещё и образ .sparsebundle создавать, и монтировать ещё и его. Всё это, возможно, и не сильно напрягает, если делать раз в пару недель на стационарном ПК, который постоянно находится в одной и той же сети и не выключается так же, как и сервер. Но когда это надо делать после каждого включения/пробуждения ноутбука — это ни в какие ворота не лезет. Плюс к этому выяснилось, что если не отмонтировать разделы и сменить сеть (скажем прийти к соседу в гости), то система изрядно виснет после выхода из сна, ибо не находит сервер с шарами, а, в редких случаях, ещё и в kernel panic случается. Всё это сильно омрачило радость поднятия сервера и мечты о том что больше я даже вспоминать не буду о бэкапах, пока они мне не понадобятся (тьфу тьфу тьфу). Было решено, что процесс нужно автоматизировать.
На первых порах
В попыхах были нагуглены способы монтирования самбы и тут же родился маленький скрипт из парочки идентичных команд следующего вида:
mkdir -p /mount/point
Так же было найдено как сделать аттач образа для TimeMachine:
hdiutil attach -mountpoint /mount/point /path/to/image.sparsebundle/
hdutil оказался более смышлёным и создание папок не потреловал.
Первая версия скрипта была готова.
Безопасность
Очень напрягало указание пароля в явном виде при монтировании. Почитав ман для mount_smbfs узнал про nsmb.conf. Но идея так же не шибко понравилась, так как всё равно пароль хранится где-то в файле в открытом виде. Тут же вспомнил, что через GUI пароль спрашивают единожды, а далее вытаскивают из keychain. Захотелось использовать её. Оказалось автоматически, как если бы взял nsmb.conf и дописал ключик -N к mount_smbfs, пароль подставляться не будет (чуда не произошло). Прийдёся его сначала получать через security и затем передавать в нужное место. Для сих целей была нагуглена и переделана под свои нужды функция:
get_inet_pwd () { security 2>&1 >/dev/null find-internet-password -gl $1 \ |ruby -e 'print $1 if STDIN.gets =~ /^password: "(.*)"$/' }
После этого явное указание пароля было заменено на:
mount -t smbfs //user:"$(get_inet_pwd server-pc)"@server-pc/shara_name /mount/point
Паранойя отступила, но любознательность и перфекционизм остались, поэтому дело продолжилось.
Улучшения и расширение
Захотелось сделать один скрипт для монтирование всего и сразу, да так сделать, чтобы он расширяемый было и повторять код много раз не пришлось, плюс чтобы смотрел что уже в системе примонтировано и второй раз монтировать не пытался. Сказано — сделано. Опишу всё по-порядку.
Для определения примонтированости, на первом этапе, был использован самый «топорный» метод
if [ ! -d /mount/point/ ]; then mkdir -p /mount/point mount … fi
Но сразу же стало понятно, что директория может и присутствовать, но не являться точкой монтирования для чего-либо. Поэтому сделал функцию для проверки:
is_volume_mounted() { volume_name=$1 mount | awk -v volume_name=$volume_name '$3 == volume_name {print $3}' }
Метод тоже не идеален, но уже гораздо лучше, нежели простая проверка наличия директории.
То же самое было сделано и для проверки образа бэкапа:
is_image_attached() { img_path=$1 df -Hl | awk -v img_path=$img_path '$9 == img_path {print $9}' }
После некоторых раздумий и чтения форумов метод раздулся и стал сразу проверять примонтирован ли образ, и, если нет, то монтировать его.
try_attach_fs_image() { img_path=$1 mnt_pnt_path=$2 # check existance of image file if [ -d $img_path ]; then # check if image alredy attached in system if [[ $(df -Hl | awk -v img_path=$img_path '$9 == img_path {print $9}') != "" ]]; then echo image $img_path alredy attached else hdiutil attach -mountpoint $mnt_pnt_path $img_path fi fi }
Далее нужна была функция для выполнения проверок и автоматизации по монтированию любого количества шар с сервера. Вот какой она получилась:
try_mount_server_samba() { smb_vol_name=$1 mnt_pnt_path=$2 # check if samba share exist in network if [[ $( is_samba_exist $smb_vol_name ) != "" ]]; then # check if samba alredy mounted if [[ $( is_volume_mounted $mnt_pnt_path ) != "" ]]; then # show message about that echo volume $mnt_pnt_path alredy mounted else # check if moint point directory not exist if [ ! -d $mnt_pnt_path ]; then mkdir -p $mnt_pnt_path fi # otherwise - mount volume mount -t smbfs //user:"$(get_inet_pwd server-pc)"@server-pc/$smb_vol_name $mnt_pnt_path fi fi }
Внимательный читатель заметит, что во-первых: можно и имя сервера передавать в параметрах к функции, а не хардкодить его, а во-вторых: в скрипте встречается неизвестная функция is_samba_exist.
Отвечаю по-порядку: 3-й параметр для функции было делать лень, ибо пока второго сервра с самбой не планируется; функция is_samba_exist имеет следующий вид:
is_samba_exist() { smb_vol_name=$1 smbutil view //user:"$(get_inet_pwd server-pc)"@server-pc/ | awk -v smb_vol_name=$smb_vol_name '$1 == smb_vol_name {print $1}' }
Несложно догадаться, что функция проверяет наличие шары с указанным именем в текущей сети.
Таким образом основная часть скрипта стала простой, понятной и расширяемой:
try_mount_server_samba "shara_name" "/mount/point" try_attach_fs_image "/path/to/image.sparsebundle" "/mount/point"
На последок, по образу и подобию вышеописанного скрипта, был создан ещё один, но уже для отмонтирования сразу всего:
#!/bin/sh # unmount volume if it mounted # syntax: umount_volume "/path/to/volume" umount_volume() { vol_path=$1 if [[ $(mount | awk -v vol_path=$vol_path '$3 == vol_path {print $3}') != "" ]]; then umount $vol_path echo $vol_path is unmounted fi } # detach filesystem image if it attached # syntax: detach_fs_image "/path/to/fs/image" detach_fs_image() { img_path=$1 if [[ $(df -Hl | awk -v img_path=$img_path '$9 == img_path {print $9}') != "" ]]; then hdiutil detach $img_path echo $img_path is detched fi } # main part # umnount data volume umount_volume "/data/mount/point" # firstly detach image from backup volume detach_fs_image "/backup/image/mount/point" # secondary unmount backup volume umount_volume "/backup/volume/mount/point"
Вот и всё. Дальше скрипты были унесены к своим собратьям в ~/.script. Получили короткие алиасы в .bash_profile и стали помогать мне с самбой.
Перспективы
В будущем, когда дойдут руки, хочется подружить скрипты со SleepWatcher, дабы выполнялись они после выхода из сна и перед уходом в него же. То есть, чтобы совсем ничего не надо было делать руками и автоматизация стала полной.
ссылка на оригинал статьи http://habrahabr.ru/post/232087/
Добавить комментарий