--- /dev/null
+Sysadmin Automation with Git Hooks
+Extending git push into a config application tool
+2022-03-28
+
+When I first created my VPS, I edited config files and made a note in a file in
+my home directory and that was it. If I were to ever move to a different VPS,
+then I would've copied over the notes file and all the files it mentions and set
+things up manually. Pragmatically, this is a perfectly acceptable setup given I
+have very little on my VPS and so far have only moved once in the 5 or so years
+I have been administering a server for. However, it has no form of version
+control and requires doing all the work through an ssh session which isn't
+always desirable.
+
+I recently came across [this blog post](https://toroid.org/git-website-howto)
+explaining how a `post-receive` git hook can be used to automatically update a
+website's content when the repository is pushed to and decided to make some use
+of it. Currently, I use a makefile rule like this to send my built site to my
+VPS independently of pushing:
+
+```push: site
+ rsync --exclude-from=rsync-excludes -ruzv ./ user@host:/var/www/
+```
+
+This is what I am continuing to use as my website's repository is not just
+static files, and it relies on a handful of more obscure and self-made tools.
+However, in the case of the VPS config files this can work perfectly.
+
+I moved all those config files and things for my VPS into a private git
+repository with a tree mirroring where they lie in my system. I also put the
+notes in that repo so I always have them easily accessible, then I just have
+this `post-receive` hook (which goes in the `hooks` directory of the bare git
+repo on the server that's being pushed to):
+
+```mkdir /tmp/vps
+GIT_WORK_TREE=/tmp/vps git checkout -f main
+sudo rsync --exclude-from=/tmp/vps/rsync-excludes -rv /tmp/vps/ /
+git diff-tree --no-commit-id --name-only -r \
+ $(git rev-parse --verify HEAD) > /tmp/vps/modified
+grep nginx.conf /tmp/vps/modified \
+ && sudo systemctl restart nginx
+rm -rf /tmp/vps
+```
+
+What this does is first create a temporary directory the tree can be checked out
+to. Then it uses `rsync` to apply the config files to the system. Next it gets a
+list of all the files that were modified in the last commit and restarts
+services if files relating to them were affected (in the example I'm just doing
+this for `nginx`, but in the real one I use it for several other files too).
+
+Note that there is the caveat that you'll need to allow the user running the git
+commands (the one you're pushing as) to run the `systemctl` and `rsync` commands
+with `sudo` without a password as they will not run interactively.
+
+The result of this setup is I now have all my server's config files version
+controlled, more easily accessible for tweaking, and a handful of menial tasks
+are automated for me!
--lpur : #d56ef7 ;
--pink : #ff297f ;
--cyan : #00ffff ;
+
+ --red : #f44336 ;
+ --grn : #66bb6a ;
+ --ylw : #fb8c00 ;
+ --blu : #3281ea ;
+ --mag : #ba68c8 ;
+ --cyn : #f06292 ;
}
/* FONTS */
src : url( '/font/Savior4.ttf' ) ;
}
+@font-face {
+ font-family : Hurmit ;
+ src : url( '/font/Hurmit-Nerd-Font-Mono.otf' ) ;
+}
+
@font-face {
font-family : Atkinson ;
src : url( '/font/Atkinson-Hyperlegible-Regular.ttf' ) ;
p , ul { font-size : clamp( 1em , 5vw , 2em ) ; }
ul { list-style-type : '- ' ; }
+p { text-align : justify ; }
+
+code {
+ font-family : Hurmit, monospace ;
+ text-align : left ;
+ white-space : pre-wrap ;
+ font-size : clamp( 0.5em , 3.5vw , 0.8em ) ;
+ margin : 0 ;
+ padding : 0.25em 0.4em ;
+ border-radius : 0.2em ;
+ background-color : var(--g) ;
+ display : inline-block ;
+}
time {
color : var(--grey) ;