Managing configuration files with ‘deploy’
The 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
changing my $HOME
into a git repository.
History
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
The 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
(e.g. in /etc
or /usr/local/etc
), create filelist.root
and run
deploy
as the root user.
file format
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
deploy
is 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
profile
as/home/jdoe/.profile
. - The rest of the line is considered the post-install commands. This may be empty and may contain spaces.
commands
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.
Examples
The file 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'.
Download
As of May 2015, the source code repository is now available on github.
Requirements
The deploy
program was written for Python 3 (developed and tested with
python3.4
). It has no dependencies outside of Python’s standard library.
Note
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
Installation
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.py
script to a location in your path asdeploy
- Make it executable.
For example
# 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.
Note
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.
Windows
Copy 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.
Related articles
- Profiling Python scripts(6): auto-orient
- Profiling with pyinstrument
- From python script to executable with cython
- On Python speed
- Python 3.11 speed comparison with 3.9