umask per directory


I’ve been working with Puppet some time now, and we are configuring our way through a lot of hosts, with 6 persons, all working in the same Puppet master directory.

This should work fine with all UNIX/Linux groups and setgid directories. But simple problem arose with the git version control stuff.

Once in a while the complete git repo was destroyed and quite a lot of searching revealed the reason why.

We are all working as non-root and we are all members of the Puppet group. But: When I edit a file and commit it, the corresponding files in the git repo are made by me and the rights are set according to my umask. When someone else tries to edit the same file or something else which results in the same hash files, writing is not permitted, because of my ownership. A chown in a script will not work, as a chown is not honored as a non-root user.

This problem can simply be solved by setting the umask to something like 007 (or u=gwx,g=gwx,o=). But when I do edit stuff in my home-directory I do not want an open umask like that. So what to do, as ext[234] do not support per directory umasks.

I use zsh as a shell and I found a nice function in the man-page. There is a standard function, called chpwd() that gets executed every time a directory change is made. So I only had to fill in the blanks.

This is what I came up with:

chpwd()
{
    case "${PWD}/"
    in
        /etc/puppet/*)
            [[ ${UMSAVE} = 0 ]] &&
            {   um=$(umask)
                UMSAVE=1
            }
            umask 007
        ;;
        *)
            [[ x"${um}" != x"" ]] && umask ${um}
            UMSAVE=0
        ;;
    esac
}

Now, when I change to the directory /etc/puppet I do get a umask of 007 and when I cd somewhere else, I do get the original umask.

How much fun can it be ;-)

See also