The configuration of a linux server will change over time. Keeping track of the changes of all the configuration files can be a challenge. etckeeper is a utility that makes this easy.
With the help of etckeeper, the complete /etc/ directory is placed under version control. It supports many different version control systems like git, mercurial and more. For this setup I will use git as the repository for etckeeper. To install etckeeper and git from the yum repository, run the following command.
$ yum install etckeeper git
After the packages are installed, you can edit the /etc/etckeeper/etckeeper.conf file to define the “VCS” (Version Control System). By default, git is configured as the VCS. With the package from the repository, the configuration for the package manager is also already pre-configured.
To get the /etc/ directory under version control, the next step is to initialize the repository for etckeeper. This is done by running etckeeper with the “init” argument.
$ etckeeper init Initialized empty Git repository in /etc/.git/
This will, as the output shows, initialise the git repository inside the /etc/ directory. To commit the initial version of all the configuration files, run the following command. The last parameter contains the git commit message (where you can include whatever description you like).
$ etckeeper commit "commit initial version of files"
You might notice in the /etc/ directory a file called /etc/.etckeeper which contains detailed information about the files etckeeper is managing in the repository. As git does not care about file owners or file permissions, etckeeper stores this extra information in this file, which is also committed to its repository.
Integration into the system
Etckeeper will automatically integrate into the package manager of your system while installing. This allows it to run before and after packages are installed or updated. As shown in the example yum output below, etckeeper integrates into the package manager and will execute a “pre transaction commit” as well as a “post transaction commit” while installing new packages.
$ yum install htop Loaded plugins: etckeeper, fastestmirror, priorities Loading mirror speeds from cached hostfile * Webmin: download.webmin.com * base: mirror.rackspace.com * epel: dl.fedoraproject.org * extras: mirror.hmc.edu * rpmforge: mirror.webnx.com * updates: dallas.tx.mirror.xygenhosting.com 4 packages excluded due to repository priority protections Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package htop.x86_64 0:1.0.3-1.el6.rf will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: htop x86_64 1.0.3-1.el6.rf rpmforge 87 k Transaction Summary ================================================================================ Install 1 Package(s) Total download size: 87 k Installed size: 209 k Is this ok [y/N]: y Downloading Packages: htop-1.0.3-1.el6.rf.x86_64.rpm | 87 kB 00:00 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction etckeeper: pre transaction commit [master e67e756] saving uncommitted changes in /etc prior to yum run 16 files changed, 24 insertions(+), 3 deletions(-) Installing : htop-1.0.3-1.el6.rf.x86_64 1/1 etckeeper: post transaction commit Verifying : htop-1.0.3-1.el6.rf.x86_64 1/1 Installed: htop.x86_64 0:1.0.3-1.el6.rf Complete!
This will ensure one commit before the packages have installed as well as one after the installation. With this in place, there will be a copy of any configuration file installed to /etc/ from the package. This can be useful if you ever need to revert the configuration to its default state.
The commit messages you will find in the repository will look like the following two.
saving uncommitted changes in /etc prior to yum run committing changes in /etc after yum run
Depending on the package you install and the state of the repository, you might have only one commit as in the example yum output above. As the tool “htop” does not change the /etc/ directory, there will be no commit after the yum run. If the /etc/ directory had been not modified before the yum run, there will even not be a commit from before the package was installed.
Add a remote git repository
To keep a copy of the files etckeeper is managing in a remote location, you can add a remote repository to the local git repository. This is not done through etckeeper but through the following git command.
Change to the /etc/ directory and execute the following command to add a remote to the git repository. The second command shows the remote has been added.
$ git remote add origin ssh://git@repo.example.com:1234/etckeeper-repository-name.git $ git remote -v origin ssh://git@repo.example.com:1234/etckeeper-repository-name.git (fetch) origin ssh://git@repo.example.com:1234/etckeeper-repository-name.git (push)
As shown in the output above, the remote that was added is called “origin” as specified. etckeeper is able to push the changes to the remote every time something is committed. To let etckeeper know you want to do this, edit the etckeeper configuration file and define the remote name.
$ vim /etc/etckeeper/etckeeper.conf
Change the setting shown below to the name of the remote you specified when adding the remote.
PUSH_REMOTE="origin"
Now when yum is run and files are changed in the /etc/ directory, etckeeper will show output like this. The output shows how etckeeper commits the changes to the local repository and then pushes them to the remote repository.
$ yum install smartmontools Loaded plugins: etckeeper, fastestmirror, priorities Loading mirror speeds from cached hostfile * Webmin: download.webmin.com * base: mirror.rackspace.com * epel: dl.fedoraproject.org * extras: mirror.hmc.edu * rpmforge: mirror.webnx.com * updates: dallas.tx.mirror.xygenhosting.com 2 packages excluded due to repository priority protections Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package smartmontools.i686 1:5.43-1.el6 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: smartmontools i686 1:5.43-1.el6 base 395 k Transaction Summary ================================================================================ Install 1 Package(s) Total download size: 395 k Installed size: 1.3 M Is this ok [y/N]: y Downloading Packages: smartmontools-5.43-1.el6.i686.rpm | 395 kB 00:00 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction etckeeper: pre transaction commit [master 467c74e] saving uncommitted changes in /etc prior to yum run Author: username <username@example.com> 18 files changed, 2351 insertions(+), 3 deletions(-) Counting objects: 48, done. Delta compression using up to 2 threads. Compressing objects: 100% (24/24), done. Writing objects: 100% (25/25), 11.71 KiB, done. Total 25 (delta 20), reused 0 (delta 0) To ssh://git@repo.example.com:1234/etckeeper-repository-name.git a1a75ec..467c74e master -> master Installing : 1:smartmontools-5.43-1.el6.i686 1/1 etckeeper: post transaction commit Counting objects: 27, done. Delta compression using up to 2 threads. Compressing objects: 100% (15/15), done. Writing objects: 100% (16/16), 5.53 KiB, done. Total 16 (delta 10), reused 0 (delta 0) To ssh://git@repo.example.com:1234/etckeeper-repository-name.git 467c74e..839b58f master -> master Verifying : 1:smartmontools-5.43-1.el6.i686 1/1 Installed: smartmontools.i686 1:5.43-1.el6 Complete!
The package installed here includes changes to the /etc/ directory, causing a commit and push before and after the package is installed.
If you have files in the /etc/ directory that change often as happens with webmin and its “System and Server Status”. Those and other files can be set to be ignored using the .gitignore file.
Manually committing changes
When you change the configuration files in /etc/ manually, there is no hook that triggers eckeeper to handle the changed files. In this case you need to execute etckeeper manually. With the following command it is possible to check if there are uncommitted changes in the git repository.
$ etckeeper vcs status # On branch master # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: ssh/sshd_config # no changes added to commit (use "git add" and/or "git commit -a")
If you have uncommitted changes, the following command can be executed to commit them into the repository.
$ etckeeper commit "updated sshd config" [master 438c43a] updated sshd config Author: username <username@example.com> 1 files changed, 1 insertions(+), 0 deletions(-) Counting objects: 7, done. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 366 bytes, done. Total 4 (delta 3), reused 0 (delta 0) To ssh://git@repo.example.com:1234/etckeeper-repository-name.git 9ab4abc..438c43a master -> master
Read more of my posts on my blog at http://blog.tinned-software.net/.