1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
etckeeper is a collection of tools to let /etc be stored in a git
repository. It hooks into apt to automatically commit changes made to /etc
during package upgrades. It uses `metastore` to track file metadata that
git does not normally support, but that is important for /etc, such as the
permissions of `/etc/shadow`. It's quite modular and configurable, while
also being simple to use if you understand the basics of working with git.
## security warning
First, a big warning: By checking /etc into revision control, you are
creating a copy of files like /etc/shadow that must remain secret. Anytime
you have a copy of a secret file, it becomes more likely that the file
contents won't remain secret. etckeeper is careful about file permissions,
and will make sure that repositories it sets up don't allow anyone but root
to read their contents. However, you *also* must take care when cloning
or copying these repositories, not to allow anyone else to see the data.
Since git mushes all the files into packs under the .git directory, the
whole .git directory content needs to be kept secret. Also, since git
doesn't keep track of the mode of files like the shadow file, it will check
it out world readable, before etckeeper fixes the permissions. The tutorial
has some examples of safe ways to avoid these problems when cloning an /etc
repository.
## what etckeeper does
etckeeper has special support to handle changes to /etc caused by
installing and upgrading packages. Before apt installs packages,
`etckeeper pre-apt` will check that /etc contains no uncommitted changes.
After apt installs packages, `etckeeper post-apt` will add any new
interesting files to the repository, and commit the changes.
git is designed as a way to manage source code, not as a way to manage
arbitrary directories like /etc. This means it has a few limitations that
etckeeper has to work around. These include file metadata storage,
empty directories, and special files.
git has only limited tracking of file metadata, being able to track the
executable bit, but not other permissions or owner info. So file metadata
storage is handled by `metastore`. Amoung other chores, `etckeeper init`
sets up a git hook that use `metastore` to store metadata about file
owners, permissions, and even extended attributes into a /etc/.metadata
file. This metadata is stored in git along with everything else, and can be
applied if the repo should need to be checked back out.
git cannot track empty directories. So `etckeeper init` also sets up a git
hook to run `etckeeper pre-commit`, which checks for empty directories
before committing, and warns about them. You can then either ignore the
empty directory, if it's not significant, or put a file (such as
`.gitignore`) in the directory to enable git to track it.
git doesn't support several special files that you _probably_ won't have in
/etc, such as unix sockets, named pipes, hardlinked files (but softlinks
are fine), and device files. Again git hooks are used to warn if your /etc
contains such untrackable special files.
## tutorial
A quick walkthrough of using etckeeper.
cd /etc
etckeeper init
This `etckeeper init` command initialises an /etc/.git/ repository. This
command is careful to never overwrite existing files or directories in
/etc. It will create a `.gitignore` if one doesn't already exist, sets up
git hooks if they don't already exist, and so on. It does *not* commit any
files into to git, but does `git-add` all interesting files for an initial
commit. So you might want to use git status to check that it includes all
the right files, and none of the wrong files. And you can edit the
.gitignore and so forth. Once you're ready:
git commit -m "initial checkin"
git gc # pack git repo to save a lot of space
After this first checkin, you can use regular git commands to check in
further changes:
passwd someuser
git status
git commit -a -m "changed a password"
Rinse, lather, repeat.
etckeeper hooks into apt so changes to files in /etc caused by installing or
upgrading packages will automatically be committed. (`etckeeper post-apt`
uses `git-add .`, so any new files in /etc that arn't gitignored will be
added. If it auto-adds files you don't want added, put them in
`.gitignore`.)
You can use any git commands you like, but do keep in mind that, if you
check out a different branch or an old version, git is operating directly
on your system's /etc. Often it's better to clone /etc to elsewhere and do
potentially dangerous stuff in a staging directory. You can clone the
repository using git-clone, but be careful that the directory it's cloned
into starts out mode 700, to prevent anyone else from seeing files like
shadow, before `etckeeper init` fixes their permissions:
mkdir /my/workdir
cd /my/workdir
chmod 700 .
git clone /etc
cd etc
etckeeper init
chmod 755 ..
Another common reason to clone the repository is to make a backup to a
server. When using git-push to create a new remote clone, make sure the new
remote clone is mode 700! (And, obviously, only push over a secure
transport like ssh, and only to a server you trust.)
ssh server 'mkdir /etc-clone; cd /etc-clone; chmod 700 .; git init'
git push ssh://server/etc-clone master
Of course, it's also possible to pull changes from a server onto client
machines, to deploy changes to /etc. You might even set up branches for
each machine and merge changes between them. Once /etc is under version
control, the sky's the limit..
## configuration
Each etckeeper command uses `run-parts` to run the executable files in
`/etc/etckeeper/$command.d/`. By default these directories contain a bunch of
symlinks to the actual files; you can remove or reorder the symlinks, or
add your own custom files. Each individual file is short, simple, and does
only one action. You can even just symlink in existing programs to run
them.
For example, here's how to configure it to run `git-gc` after each apt run,
which will save a lot of disk space:
cd /etc/etckeeper/post-apt.d
ln -s /usr/bin/git-gc 99git-gc
git add .
git-commit -m "run git-gc after each apt run"
Note that the etckeeper commands are careful to not hardcode anything about
git. If you want to use some other revision control system, that's
theoretically possible to accomplish by just changing the files in
/etc/etckeeper/. If you do this, please let me know.
## inspiration
Two blog posts provided inspiration for techniques used by etckeeper:
* http://www.jukie.net/~bart/blog/20070312134706
* http://bryan-murdock.blogspot.com/2007/07/put-etc-under-revision-control-with-git.html
isisetup (http://www.isisetup.ch/) has some of the same aims as etckeeper,
however, unlike it, etckeeper does not aim to be a git porcelain with its
own set of commands for manipulating the /etc repository. Instead,
etckeeper provides a couple of simple tools and hooks for setting up an /etc
repsository, and then gets out of your way; you manage the repository using
regular git commands.
## author
Joey Hess <joey@kitenet.net>
|