30 авг 2017
caspar
20170830
NAME
caspar - Makefile snippets for common tasks
SYNOPSIS
In a Makefile, write either
include caspar/mk/caspar.mk
or
include caspar/mk/docbook.mk
or
include caspar/mk/pod.mk
.
DESCRIPTION
Caspar offers Makefile snippets for common tasks, like installing
(configuration) files, or typesetting LaTeX, DocBook XML and DocBook SGML
documents.
The typesetting functionality is delivered by docbook.mk and pod.mk.
This is documented in caspar-typesetting(7).
The installing-stuff functionality is delivered by caspar.mk.
(That's what the rest of the manual will talk about.) It enables one to run
'make install' from within a tree which typically holds configuration files,
managed using Subversion (or git or any other version control system, for that
matter).
It is useful in cases like this: all configuration files of some host are under
version control, and, after commiting a change to CVS, you want to be able to
easily install the new configuration file on the host.
With caspar, all you have to do is specify the hostname in one place, and
specify the name of the target directory in each CVS directory.
It is comparable with other tools for Unix system administrators like
puppet and cfengine. Main difference: the caspar code consists of less than
100 lines of GNU Make.
USAGE
Within a CVS tree, create a file include/install.mk, with contents like
e.g.
csp_UHOST = root@some.host.somewhere
include caspar/mk/caspar.mk
. Within each other directory of the CVS tree which holds files, create a
Makefile, which looks like e.g.
csp_DIR = /some/dir/ectory/
include ../../include/install.mk
.
If you'd like to use the install-recursive target too, in directories
which hold subdirectories (but not files), you'll have to create a Makefile
which looks something like
include ../../include/install.mk
. From within the CVS tree, one can call:
make <filename>-diff
make <filename>-install
make diff
make install
make load
make
make install-recursive
Calling make <filename>-diff shows the diff between the local file
and the file as currently installed on the remote location.
Calling make install (or make) now will scp all files in the current
directory to the remote location. The install-recursive target descends
down the tree, and calls make install in each subdirectory.
Of course, you'll have to be able to ssh directly as root to the remote host to
get this working (if you'd like to use csp_UHOST =
root@some.host.somewhere). If you don't like this, and would like to have a
PermitRootLogin no in your /etc/ssh/sshd_config, you can use
csp_sucp(1). See below.
VARIABLES
The variables one can set in a calling Makefile are:
user@host, reachable using $(csp_PUSH) (which
is scp by default)
space separated list of user@host items, reachable
using $(csp_PUSH)
directory on host, reachable using function
$(csp_PUSH)
make function for pushing files to remote location.
Usually, this is a wrapper around a script or
program. The function will be passed 4 arguments:
[user@]host, remote directory and local
filename.
[user@]host will be set
to all elements of $(csp_UHOSTS);
directory will be set to $(csp_DIR).
Currently, $(csp_scp_FUNC), $(csp_cp_FUNC)
and $(csp_sucp_FUNC) are supported as push
plugins. If csp_PUSH is unset, the default
$(csp_scp_FUNC) is used.
the `load' target depends upon these targets.
the `build' target depends upon these targets.
cp binary, just "cp" by default
scp binary, just "scp" by default
script wrapping sudo in ssh, "csp_sucp" by default
extra files which should be installed.
Can be used to include files starting with a dot.
files which should never be installed. Set to
Makefile .%.swp %~ #%# pod2htmd.tmp pod2htmi.tmp by default.
extra files which should never be installed;
added to list in csp_TABOOFILES.
files which should be installed, even if
in initial csp_TABOOFILES list. Removed from csp_TABOOFILES
list.
directories to exclude in install-recursive target.
set to CVS .svn by default.
csp_TABOODIRS_ADD, csp_TABOODIRS_SKIP
see
csp_TABOOFILES equivalents.
override csp_UHOSTS: don't push to csp_UHOSTS, but
to the intersection of this space separated list of user@host items and
csp_UHOSTS.
The following variables might get phased out or removed soonish:
extra arguments to pass to cp invocation, none by
default
extra arguments to pass to scp invocation, e.g.
'-i .ssh/id_rsa-root'
EXAMPLES
Some examples:
Using csp_UHOST
This is the simplest way to use caspar. Makefile is
csp_UHOST = root@some.host.somewhere
csp_DIR = /etc/
include caspar/mk/caspar.mk
Now, running "make" will scp all files in the current directory to
root@some.host.somewhere:/etc/.
More hosts, not scp but sudo via ssh: using csp_PUSH
Makefile is
csp_UHOSTS = root@some.host.somewhere root@some.other.host
csp_PUSH = $(csp_sucp_FUNC)
csp_DIR = /etc/
include caspar/mk/caspar.mk
Now, running "make" will use csp_sucp(1) to install all files in the current
directory to both root@some.host.somewhere:/etc/ and
root@some.other.host:/etc/. If a file named fstab is present in the
current directory, running "make fstab-install" will just install that one
file.
If you need to sudo(1) to another user on the remote host, add something like
csp_XARG = postgres
. (If such a username is not supplied, sudo (and csp_sucp) use the default:
root.)
Overriding csp_UHOSTS: csp_UHOSTS_SKIP
If one or some of your hosts are temporarily unavailable, and you'd like to
push your files to the hosts which are alive, you can temporarily override your
csp_UHOSTS. E.g., when some.other.host is not available:
% cat Makefile
csp_UHOSTS = root@some.host.somewhere root@some.other.host
csp_DIR = /etc/
include caspar/mk/caspar.mk
% make install csp_UHOSTS_SKIP=root@some.other.host
scp hosts root@some.host.somewhere:/etc/
scp fstab root@some.host.somewhere:/etc/
Overriding csp_UHOSTS in a smart way: csp_UHOSTS_SUBSET. Using multiple
groups of hosts. Recursive make made easy.
If you have lots of subdirectories holding information for lots of groups of
hosts, while this run you just want to install for a small group (or 1) hosts,
csp_UHOSTS_SUBSET is useful.
Suppose your casparized tree looks like
Makefile
apache/include/install.mk
apache/etc/apache2/Makefile
apache/etc/apache2/envvars
php/include/install.mk
php/etc/php4/apache/Makefile
php/etc/php4/apache/php.ini
grub/include/install.mk
grub/boot/grub/Makefile
grub/boot/grub/menu.lst
logrotate/include/install.mk
logrotate/etc/Makefile
logrotate/etc/logrotate.conf
nrpe/include/install.mk
nrpe/debian/etc/default/Makefile
nrpe/debian/etc/default/nagios-nrpe-server
The file apache/etc/apache2/Makefile is:
csp_DIR = /etc/apache2/
include ../../include/install.mk
(all other Makefiles are similar).
The file apache/include/install.mk is
csp_UHOSTS = root@a root@b
include caspar/mk/caspar.mk
The file php/include/install.mk is the same. The files
grub/include/install.mk and logrotate/include/install.mk are
csp_UHOSTS = root@d root@e root@f root@g
include caspar/mk/caspar.mk
The file nrpe/include/install.mk is
csp_UHOSTS = root@d root@e root@f root@n
include caspar/mk/caspar.mk
The toplevel Makefile is
dirs = $(patsubst %/Makefile,%,$(shell find * -mindepth 1
-name Makefile))
all:
for i in $(dirs); do $(MAKE) -$(MAKEFLAGS) -C $$i; done
install
for i in $(dirs); do $(MAKE) -$(MAKEFLAGS) -C $$i install; done
load
for i in $(dirs); do $(MAKE) -$(MAKEFLAGS) -C $$i load; done
(we don't feel like sticking a Makefile in all non-leaf nodes of our tree).
Now, when running "csp_UHOSTS_SUBSET='root@e root@f root@m root@n' make"
in the toplevel, caspar just takes the intersection of csp_UHOSTS_SUBSET and
csp_UHOSTS for each csp_UHOSTS list. So, caspar will not push anything for
apache/ and php/. The files grub/boot/grub/menu.lst and
logrotate/etc/logrotate.conf will get pushed to root@e and
root@f only. The file nrpe/debian/etc/default/nagios-nrpe-server
will get pushed to root@e, root@f and root@n.
This is often better than just overriding csp_UHOSTS on the commandline (or in
your shell's environment): if the intersection of the original csp_UHOSTS and
your new csp_UHOSTS is empty, chances are big you've just forgotten to clean
your environment.
Creating remote directories if needed
Makefile is
csp_DIR = /some/dir/ectory/
csp_PUSH = $(csp_scpmkdir_FUNC)
csp_UHOST = root@some.host.somewhere
include caspar/mk/caspar.mk
Now, before calling scp, caspar will run 'mkdir -p' to create any missing
remote directories.
Using csp_CP and csp_LOAD
username/etc/Makefile is
csp_UHOST = dummy
csp_PUSH = $(csp_cp_FUNC)
csp_DIR = $(HOME)/etc/
csp_LOAD = crontab-load
include ../include/install.mk
crontab-load = crontab $(csp_DIR)/crontab
while ../include/install.mk is just
include caspar/mk/caspar.mk
.
Setting csp_PUSH to $(csp_cp_FUNC) causes cp(1) to get executed
by "make install" (not scp(1)).
Setting csp_LOAD causes "make load" to execute the crontab command. Just
running "make" is OK too, since "make" calls both "make install" and "make
load".
Using csp_DIR, csp_LOAD and install(1)
To install a file on the local host, create e.g. a file etc/uruk/Makefile
like:
csp_UHOST = dummy
csp_DIR = /etc/uruk/
csp_PUSH = $(csp_install_FUNC)
csp_LOAD = uruk-load
include caspar/mk/caspar.mk
uruk-load = sudo invoke-rc.d uruk force-reload
Using csp_DIR and csp_LOAD, take 2
etc/Makefile is
csp_DIR = /etc/
csp_LOAD = aliases-load
include ../include/install.mk
aliases-load = $(csp_SSH) $1 "cd /etc && postalias aliases; postfix reload"
while ../include/install.mk is
csp_UHOST = root@some.host.somewhere
include caspar/mk/caspar.mk
Building files locally
Note: csp_BUILD is deprecated. You should not use it.
If you'd like to build some files locally from local sources, before installing
the just built files, do e.g.:
csp_UHOST = root@some.host.somewhere
csp_DIR = /etc/
csp_EXTRAFILES = sshd_config
csp_TABOOFILES_ADD = sshd_config.m4
include caspar/mk/caspar.mk
sshd_config: sshd_config.m4
m4 $< > $@
List all source files in csp_TABOOFILES_ADD: this way, they won't get installed
on the csp_UHOST.
Using csp_sucp_FUNC and csp_LOAD
If you'd like to use csp_sucp and want a `load' target, do something like:
csp_PUSH = $(csp_sucp_FUNC)
csp_UHOST = foobar.example.com
csp_DIR = /etc/uruk/
csp_LOAD = rc-load
include caspar/mk/caspar.mk
rc-load = $(csp_SSH) $1 sudo invoke-rc.d uruk force-reload