Programs of Hyper

How-To store /etc in a git repository on debian linux

What this howto do? (Updated with "Buster" in 2021)

Create and set up the repository

First of all install the necessary packages. Git for versionig, and metastore for save-restore permissions of files and folders.

apt install metastore
Create a directory in etc to store scripts used by apt hooks
mkdir /etc/etc-git

/etc/etc-git/aptpreinstall.bashDownload

#!/bin/bash GITSTATUSOUT=`(cd /etc;git status|grep 'nothing to commit, working tree clean')` GITDIFFOUT=`(cd /etc;git diff)` if test "$GITSTATUSOUT" != "nothing to commit, working tree clean" || test "$GITDIFFOUT" != "" then echo -e "\n\n !!!WARNING!!! Uncomitted changes in /etc !!!WARNING!!!" echo -e " ( Run: eg-commit )\n" exit 1 fi exit 0

/etc/etc-git/aptpostinstall.bash Download

#!/bin/bash GITSTATUSOUT=`(cd /etc;git status|grep 'nothing to commit, working tree clean')` GITDIFFOUT=`(cd /etc;git diff)` DATE=`date` if test "$GITSTATUSOUT" != "nothing to commit, working tree clean" || test "$GITDIFFOUT" != "" then echo -e "\n===== /etc changed need git commit =====" ( cd /etc/ /usr/local/bin/eg-save git add --all git commit . -m "Automatic commit after apt ($DATE)" ) echo -e "\n===== Comitted =====" exit 0 fi exit 0

Setting up apt hooks to use the scripts created above.
chmod +x /etc/etc-git/*.bash
echo "DPkg::Pre-Invoke { '/etc/etc-git/aptpreinstall.bash' };" \
    >> /etc/apt/apt.conf.d/90etc-git
echo "DPkg::Post-Invoke { '/etc/etc-git/aptpostinstall.bash' };" \
    >> /etc/apt/apt.conf.d/90etc-git
This hooks made:
Now let's create an empty repository and set up some metadata.
cd /etc
git init
echo "System ETC stored in GIT" > /etc/.git/description
git config --global user.name "Your Name"
git config --global user.email you@example.com
Create some script file in /usr/local/bin

/usr/local/bin/eg-saveDownload

#!/bin/bash cd /etc metastore -s

/usr/local/bin/eg-restoreDownload

#!/bin/bash cd /etc metastore -aeq

/usr/local/bin/eg-checkDownload

#!/bin/bash CHKRES=`cd /etc;metastore -c` if test "$CHKRES" != "" then echo -e "The permission structure of the /etc is changed\n" echo -e "Run: eg-save" exit 1 fi exit 0

/usr/local/bin/eg-commitDownload

#!/bin/bash if test "$1" == "" then echo "Missing parameter!" echo " use: eg-commit \"Commit text\"" exit 1 fi cd /etc echo "Save permissions (eg-save)..." eg-save echo "Add all non versioned items to git (git add --all)..." git add --all echo "Do commit (git commit .)..." git commit . -m "$1"

Now we need to create a git "pre-commit" hook to check wheter the permissions are saved before commit.
This hook warn you if the permissions of /etc changed and tell you to run eg-save before commit.
(You think it would be nice to put "eg-save" into this "pre-commit" hook, but unfortunately the git doesn't allow to change the versioned files in this hook)
To create the hook create this file

/etc/.git/hooks/pre-commitDownload

#!/bin/bash /usr/local/bin/eg-check

Don't forget to make this scripts executable
chmod +x /usr/local/bin/eg-*
chmod +x /etc/.git/hooks/pre-commit
And finally put the current etc into the git repository and do the initial commit!
eg-save
git add --all
eg-commit "Initial state"

That's it! The versioning is working now

If you change something in /etc you can easely commit your changes by command
eg-commit "Message to commit"
Of course, you can use all git command to tracking the changes of your /etc

Setting up all above with one script

This script does all the works above using the download links of the scripts.

create_etc_git.bashDownload

#!/bin/bash echo "Creating /etc/etc-git/ directory" mkdir /etc/etc-git curl http://hyperprog.com/howto/aptpreinstall.bash -o /etc/etc-git/aptpreinstall.bash curl http://hyperprog.com/howto/aptpostinstall.bash -o /etc/etc-git/aptpostinstall.bash chmod +x /etc/etc-git/*.bash echo "Set up APT hooks" echo "DPkg::Pre-Invoke { '/etc/etc-git/aptpreinstall.bash' };" \ >> /etc/apt/apt.conf.d/90etc-git echo "DPkg::Post-Invoke { '/etc/etc-git/aptpostinstall.bash' };" \ >> /etc/apt/apt.conf.d/90etc-git echo "Creating scripts in /usr/local/bin" curl http://hyperprog.com/howto/eg-save -o /usr/local/bin/eg-save curl http://hyperprog.com/howto/eg-restore -o /usr/local/bin/eg-restore curl http://hyperprog.com/howto/eg-check -o /usr/local/bin/eg-check curl http://hyperprog.com/howto/eg-commit -o /usr/local/bin/eg-commit chmod +x /usr/local/bin/eg-* echo "Initialising the git repository" cd /etc git init echo "System ETC stored in GIT" > /etc/.git/description # git config --global user.name "Your Name" # Fill this value # git config --global user.email you@example.com # Fill this value echo "Set up hook in git of etc" curl http://hyperprog.com/howto/pre-commit -o /etc/.git/hooks/pre-commit chmod +x /etc/.git/hooks/pre-commit echo "Save the current git content as initial state" eg-save git add --all eg-commit "Initial state"

Setting up remote repository (optional)

On (remote)server side we need to create the remote repository
mkdir /GITREPO/debianmachine
cd /GITREPO/debianmachine
git --bare init
Now we can set up git to use remote repository on our debian machine, and do the first push to server
cd /etc
git remote add -t master origin ssh://servername.domain.com/GITREPO/debianmachine
git push origin master
After this set up you can simply do "git push" and "git pull" later.

Author: Péter Deák
Contact Email: mailaddressat gmail.com