Managing configuration files with ‘deploy’
deploy script is a program for managing configuration files. This
script grew out of my need for a multi-functional installer for configuration
files. I tend to keep those files in a separate git repository rather than
$HOME into a git repository.
On UNIX, there is the venerable install program initially meant to install
binaries. My first installers were typically shell scripts which basically
were a list of calls to
install(1). While this works well it didn’t
completely fit my needs. Because next to purely installing a file somewhere,
I wanted to be able to do more things;
- Check for differences between the files in the repository and those in the installed location.
- Print diffs between the files in the repository and those in the installed location.
- Run arbitrary commands after a file was succesfully installed
I could of course do this with a makefile and this approach would be extremely flexible. But writing and maintaining such a Makefile would be quite cumbersome. Every file would need to have its own dependency line. And they would all have to be grouped added to a super target at the beginning of the makefile.
How it works
deploy command is meant to be run from a color terminal; it uses ANSI
escape codes to color its output.
It is meant to be used from the root of e.g. a git repository. When started,
deploy looks for and reads the file named
filelist.$USER in the
directory from which
deploy is run. So when run by a user named “jdoe” it
would look for a file
filelist.jdoe. This is suitable for installing files
in the directory tree owned by
jdoe. For installing files system wide
filelist.root and run
deploy as the root user.
In these file lists, lines that have a ‘#’ as the first non-whitespace
characters are skipped as comments. The first non-comment line must contain a
list of fully qualified host names for which this file is valid. If the name
of the host where
deploy is run is not in that list, it will quit.
The other non comment lines all have the same format:
<source path> <mode> <destination path> <post-install commands>
- The source path is path relative from the directory where
deployis called from. It may not contain whitespace.
- The mode is an octal number indicating the permissions of the destination file, see chmod(1).
- The destination path should be an absolute path including the name of
the installed file. It may not contain whitespace. The reason for including
the filename is so that you can e.g. install a file
- The rest of the line is considered the post-install commands. This may be empty and may contain spaces.
The ‘deploy’ program has tree sub-commands or modes;
- check: Generate a list of files that are different from the installed
files. If the verbose option (
-v) is used, it lists for all files if they need installing or not.
- diff: Generate a colored diff between the files in the repository and the installed files.
- install: Install the files in their destinations and run the post-install commands.
filelist.jdoe in a
setup directory contains the following
lines among others;
../shared/fetchmailrc 400 /home/jdoe/.fetchmailrc
This installs the configuration file for
fetchmail and makes sure that
only the owner can read it. Note how a relative path is used for the source,
and an absolute path is used for the destination. The first is for
convenience, the second for preventing mistakes.
The following line is an example of using post-install commands;
Xresources 644 /home/jdoe/.Xresources xrdb -load /home/jdoe/.Xresources
This reloads the X resources into the X server after installing them.
Below is a usage example;
rlyeh:~/setup/rlyeh> ./deploy check The file '../shared/muttrc' differs from '/home/jdoe/.muttrc'. rlyeh:~/setup/rlyeh> ./deploy diff The file '../shared/muttrc' differs from '/home/jdoe/.muttrc'. --- /home/jdoe/.muttrc +++ ../shared/muttrc @@ -1,5 +1,5 @@ # /home/jdoe/.muttrc -# $Date: 2014-12-19 00:46:55 +0100 $ +# $Date: 2014-12-29 02:07:58 +0100 $ # # Settings @@ -76,12 +76,11 @@ set crypt_replyencrypt = yes set crypt_replysign = yes set crypt_replysignencrypted = yes -set crypt_use_gpgme = yes set crypt_verify_sig = yes set pgp_good_sign="^gpgv?: Good signature from " set pgp_sign_as = B37C45E8 set pgp_timeout = 3600 +set pgp_use_gpg_agent=yes # # S/MIME stuff. rlyeh:~/setup/rlyeh> ./deploy install File '../shared/muttrc' was successfully installed as '/home/jdoe/.muttrc'.
As of May 2015, the source code repository is now available on github.
deploy program was written for Python 3 (developed and tested with
python3.4). It has no dependencies outside of Python’s standard library.
The script should be compatible with both Python 2 and Python 3. But it uses the latter by default. Change the first line of the script if you want to use Python 2. In that case you should also add the following line to the script:
from __future__ import print_function
UNIX-like operating systems
This includes Linux, all BSD variants, Apple’s OS X.
For a system-wide installation:
- Make sure you don’t already have an identically named program installed!
- Copy the
deploy.pyscript to a location in your path as
- Make it executable.
# install deploy.py /usr/local/bin/deploy
If you want to install it locally, just copy it to where you need it and make it executable.
If your system doesn’t have
\usr\bin\env, or if your Python 3 is not
in your $PATH, modify the first line of the deploy program to point to
the location of the Python 3 program before installing it.
deploy.py to the
scripts directory of your Python 3 installation.
Since I do not use MS windows in my development environment I’m not able to
give more specific advice.
Instead of the standard
cmd.exe shell, I would suggest you use e.g. the git
BASH that comes with MSYS git distribution.
For comments, please send me an e-mail.
- From python script to executable with cython
- On Python speed
- Python 3.11 speed comparison with 3.9
- Getting the first or last item from a dictview without a list
- Python & standard output redirection on ms-windows