📜 ⬆️ ⬇️

Automating the mounting of samba partitions on Mac OS

The third day, I raised a server for file storage, backups, torrents and other household needs. There, a samba with a multitude of balloons unfolded, in particular with personal data and space for laptop backups via TimeMachime. Immediately I did not like the constant manual mounting of the balls and the image for backup. Below I want to share with the community scripts to automate this process.

Causes of inconvenience


Each time, to connect to the samba you have to pretty much poke it with the mouse: Finder -> Connect to server -> enter the server name (-> the first time you will also be asked for the password) -> select folders to be connected -> Ok. Then, if you want to make a backup in a samba-mounted directory, you will also need to create an .sparsebundle image, and also mount it. All this, perhaps, is not very annoying, if you do it once a couple of weeks on a stationary PC, which is constantly on the same network and does not turn off the same way as the server. But when it is necessary to do this after each turning on / waking up the laptop, it does not climb into any gate. Plus, it turned out that if you do not unmount partitions and change the network (say, come to visit your neighbor), the system pretty much hangs after getting out of sleep, because it does not find a server with balls, and, in rare cases, it also happens in the kernel panic . All this greatly overshadowed the joy of raising the server and the dream that I won't even remember the more backups until I need them (pah pah pf). It was decided that the process should be automated.

At first


The ways of assembling the samba were googled in priests and a small script was born immediately from a couple of identical commands of the following type:
mkdir -p /mount/point 

It was also found how to make an image attachment for TimeMachine:
 hdiutil attach -mountpoint /mount/point /path/to/image.sparsebundle/ 
hdutil turned out to be more intelligent and did not create the creation of folders.
The first version of the script was ready.

Security


It was very annoying to specify the password explicitly when mounted. After reading the man for mount_smbfs I learned about nsmb.conf . But the idea was also not very much liked, because anyway the password is stored somewhere in the file in the clear. He immediately remembered that through the GUI, the password was asked once, and then pulled out of the keychain. I wanted to use it. It turned out automatically, as if I took nsmb.conf and added the -N key to mount_smbfs , the password will not be substituted (no miracle happened). I had to get it first through security and then transfer to the right place. For these purposes, the function was nuggled and altered to fit its needs:
 get_inet_pwd () { security find-internet-password -gwl $1 } 

After this, the explicit indication of the password was replaced by:
 mount -t smbfs //user:"$(get_inet_pwd server-pc)"@server-pc/shara_name /mount/point 

Paranoia retreated, but inquisitiveness and perfectionism remained, so the matter continued.
')

Improvements and expansion


I wanted to do one script for mounting everything at once, but to make it so that it was expandable and did not have to repeat the code many times, plus to see what was already mounted in the system and did not try to mount the second time. No sooner said than done. I will describe everything in order.

To determine the mounting, at the first stage, the most “clumsy” method was used.
 if [ ! -d /mount/point/ ]; then mkdir -p /mount/point mount … fi 

But it immediately became clear that the directory might be present, but not be a mount point for anything. Therefore, I made a function to check:
 is_volume_mounted() { volume_name=$1 mount | awk -v volume_name=$volume_name '$3 == volume_name {print $3}' } 
The method is also not perfect, but it is much better than a simple check for the presence of a directory.

The same was done to check the backup image:
 is_image_attached() { img_path=$1 df -Hl | awk -v img_path=$img_path '$9 == img_path {print $9}' } 

After some thinking and reading the forums, the method bloated and began to immediately check whether the image was mounted, and if not, then mount it.
 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 } 

Next, I needed a function to perform the checks and automation to mount any number of balls from the server. This is how it turned out:
 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 } 

The attentive reader will notice that firstly: it is possible to pass the server name in the parameters to the function, not the hardcode, and secondly: the unknown function is_samba_exist is found in the script.

I answer in order: the 3rd parameter for the function was to do laziness, for so far the second servra with samba is not planned; the is_samba_exist function has the following form:
 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}' } 
It is easy to guess that the function checks the presence of balls with the specified name in the current network.

Thus, the main part of the script has become simple, understandable and extensible:
 try_mount_server_samba "shara_name" "/mount/point" try_attach_fs_image "/path/to/image.sparsebundle" "/mount/point" 

Lastly, in the image and likeness of the script described above, another one was created, but to unmount everything at once:
 #!/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" 

That's all. Further scripts were carried away to their fellows in ~ / .script . We received short aliases in .bash_profile and began to help me with samba.

Perspectives


In the future, when the hands reach, I want to make friends with the scripts with SleepWatcher , so that they can be executed after getting out of sleep and before leaving for it. That is, that absolutely nothing needed to be done by hands and the automation became complete.

PS Thank you comrade helios for the -w key for security .

Source: https://habr.com/ru/post/232087/


All Articles