|
|
|
@ -10,7 +10,7 @@ By default this is accomplished with ssh and scp respectively.
|
|
|
|
|
The default implementations used by cdist are:: |
|
|
|
|
|
|
|
|
|
__remote_exec: ssh -o User=root |
|
|
|
|
__remote_copy: scp -o User=root |
|
|
|
|
__remote_copy: scp -o User=root -q |
|
|
|
|
|
|
|
|
|
The user can override these defaults by providing custom implementations and |
|
|
|
|
passing them to cdist with the --remote-exec and/or --remote-copy arguments. |
|
|
|
@ -26,3 +26,390 @@ specified by enclosed in square brackets (see :strong:`ssh`\ (1) and
|
|
|
|
|
With this simple interface the user can take total control of how cdist |
|
|
|
|
interacts with the target when required, while the default implementation |
|
|
|
|
remains as simple as possible. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Examples |
|
|
|
|
-------- |
|
|
|
|
|
|
|
|
|
Here are examples of using alternative __remote_copy and __remote_exec scripts. |
|
|
|
|
|
|
|
|
|
All scripts from below are present in cdist sources in `other/examples/remote` |
|
|
|
|
directory. |
|
|
|
|
|
|
|
|
|
ssh |
|
|
|
|
~~~ |
|
|
|
|
|
|
|
|
|
Same as cdist default. |
|
|
|
|
|
|
|
|
|
**copy** |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-copy "/path/to/this/script" target_host |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
#echo "$@" | logger -t "cdist-ssh-copy" |
|
|
|
|
scp -o User=root -q $@ |
|
|
|
|
|
|
|
|
|
**exec** |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-exec "/path/to/this/script" target_host |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
#echo "$@" | logger -t "cdist-ssh-exec" |
|
|
|
|
ssh -o User=root $@ |
|
|
|
|
|
|
|
|
|
local |
|
|
|
|
~~~~~ |
|
|
|
|
|
|
|
|
|
This effectively turns remote calling into local calling. Probably most useful |
|
|
|
|
for the unit testing. |
|
|
|
|
|
|
|
|
|
**copy** |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
code="$(echo "$@" | sed "s|\([[:space:]]\)$__target_host:|\1|g")" |
|
|
|
|
cp -L $code |
|
|
|
|
|
|
|
|
|
**exec** |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
target_host=$1; shift |
|
|
|
|
echo "$@" | /bin/sh |
|
|
|
|
|
|
|
|
|
chroot |
|
|
|
|
~~~~~~ |
|
|
|
|
|
|
|
|
|
**copy** |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-copy "/path/to/this/script /path/to/your/chroot" target-id |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
log() { |
|
|
|
|
#echo "$@" | logger -t "cdist-chroot-copy" |
|
|
|
|
: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
chroot="$1"; shift |
|
|
|
|
target_host="$__target_host" |
|
|
|
|
|
|
|
|
|
# replace target_host with chroot location |
|
|
|
|
code="$(echo "$@" | sed "s|$target_host:|$chroot|g")" |
|
|
|
|
|
|
|
|
|
log "target_host: $target_host" |
|
|
|
|
log "chroot: $chroot" |
|
|
|
|
log "$@" |
|
|
|
|
log "$code" |
|
|
|
|
|
|
|
|
|
# copy files into chroot |
|
|
|
|
cp $code |
|
|
|
|
|
|
|
|
|
log "-----" |
|
|
|
|
|
|
|
|
|
**exec** |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-exec "/path/to/this/script /path/to/your/chroot" target-id |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
log() { |
|
|
|
|
#echo "$@" | logger -t "cdist-chroot-exec" |
|
|
|
|
: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
chroot="$1"; shift |
|
|
|
|
target_host="$1"; shift |
|
|
|
|
|
|
|
|
|
script=$(mktemp "${chroot}/tmp/chroot-${0##*/}.XXXXXXXXXX") |
|
|
|
|
trap cleanup INT TERM EXIT |
|
|
|
|
cleanup() { |
|
|
|
|
[ $__cdist_debug ] || rm "$script" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
log "target_host: $target_host" |
|
|
|
|
log "script: $script" |
|
|
|
|
log "@: $@" |
|
|
|
|
echo "#!/bin/sh -l" > "$script" |
|
|
|
|
echo "$@" >> "$script" |
|
|
|
|
chmod +x "$script" |
|
|
|
|
|
|
|
|
|
relative_script="${script#$chroot}" |
|
|
|
|
log "relative_script: $relative_script" |
|
|
|
|
|
|
|
|
|
# run in chroot |
|
|
|
|
chroot "$chroot" "$relative_script" |
|
|
|
|
|
|
|
|
|
log "-----" |
|
|
|
|
|
|
|
|
|
rsync |
|
|
|
|
~~~~~ |
|
|
|
|
|
|
|
|
|
**copy** |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-copy /path/to/this/script target_host |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
# For rsync to do the right thing, the source has to end with "/" if it is |
|
|
|
|
# a directory. The below preprocessor loop takes care of that. |
|
|
|
|
|
|
|
|
|
# second last argument is the source |
|
|
|
|
source_index=$(($#-1)) |
|
|
|
|
index=0 |
|
|
|
|
for arg in $@; do |
|
|
|
|
if [ $index -eq 0 ]; then |
|
|
|
|
# reset $@ |
|
|
|
|
set -- |
|
|
|
|
fi |
|
|
|
|
index=$((index+=1)) |
|
|
|
|
if [ $index -eq $source_index -a -d "$arg" ]; then |
|
|
|
|
arg="${arg%/}/" |
|
|
|
|
fi |
|
|
|
|
set -- "$@" "$arg" |
|
|
|
|
done |
|
|
|
|
|
|
|
|
|
rsync --backup --suffix=~cdist -e 'ssh -o User=root' $@ |
|
|
|
|
|
|
|
|
|
schroot |
|
|
|
|
~~~~~~~ |
|
|
|
|
|
|
|
|
|
__remote_copy and __remote_exec scripts to run cdist against a chroot on the |
|
|
|
|
target host over ssh. |
|
|
|
|
|
|
|
|
|
**copy** |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-copy "/path/to/this/script schroot-chroot-name" target_host |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
log() { |
|
|
|
|
#echo "$@" | logger -t "cdist-schroot-copy" |
|
|
|
|
: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
chroot_name="$1"; shift |
|
|
|
|
target_host="$__target_host" |
|
|
|
|
|
|
|
|
|
# get directory for given chroot_name |
|
|
|
|
chroot="$(ssh -o User=root -q $target_host schroot -c $chroot_name --config | awk -F = '/directory=/ {print $2}')" |
|
|
|
|
|
|
|
|
|
# prefix destination with chroot |
|
|
|
|
code="$(echo "$@" | sed "s|$target_host:|$target_host:$chroot|g")" |
|
|
|
|
|
|
|
|
|
log "target_host: $target_host" |
|
|
|
|
log "chroot_name: $chroot_name" |
|
|
|
|
log "chroot: $chroot" |
|
|
|
|
log "@: $@" |
|
|
|
|
log "code: $code" |
|
|
|
|
|
|
|
|
|
# copy files into remote chroot |
|
|
|
|
scp -o User=root -q $code |
|
|
|
|
|
|
|
|
|
log "-----" |
|
|
|
|
|
|
|
|
|
**exec** |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-exec "/path/to/this/script schroot-chroot-name" target_host |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
log() { |
|
|
|
|
#echo "$@" | logger -t "cdist-schroot-exec" |
|
|
|
|
: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
chroot_name="$1"; shift |
|
|
|
|
target_host="$1"; shift |
|
|
|
|
|
|
|
|
|
code="ssh -o User=root -q $target_host schroot -c $chroot_name -- $@" |
|
|
|
|
|
|
|
|
|
log "target_host: $target_host" |
|
|
|
|
log "chroot_name: $chroot_name" |
|
|
|
|
log "@: $@" |
|
|
|
|
log "code: $code" |
|
|
|
|
|
|
|
|
|
# run in remote chroot |
|
|
|
|
$code |
|
|
|
|
|
|
|
|
|
log "-----" |
|
|
|
|
|
|
|
|
|
schroot-uri |
|
|
|
|
~~~~~~~~~~~ |
|
|
|
|
|
|
|
|
|
__remote_exec/__remote_copy script to run cdist against a schroot target URI. |
|
|
|
|
|
|
|
|
|
Usage:: |
|
|
|
|
|
|
|
|
|
cdist config \ |
|
|
|
|
--remote-exec "/path/to/this/script exec" \ |
|
|
|
|
--remote-copy "/path/to/this/script copy" \ |
|
|
|
|
target_uri |
|
|
|
|
|
|
|
|
|
# target_uri examples: |
|
|
|
|
schroot:///chroot-name |
|
|
|
|
schroot://foo.ethz.ch/chroot-name |
|
|
|
|
schroot://user-name@foo.ethz.ch/chroot-name |
|
|
|
|
|
|
|
|
|
# and how to match them in .../manifest/init |
|
|
|
|
case "$target_host" in |
|
|
|
|
schroot://*) |
|
|
|
|
# any schroot |
|
|
|
|
;; |
|
|
|
|
schroot://foo.ethz.ch/*) |
|
|
|
|
# any schroot on specific host |
|
|
|
|
;; |
|
|
|
|
schroot://foo.ethz.ch/chroot-name) |
|
|
|
|
# specific schroot on specific host |
|
|
|
|
;; |
|
|
|
|
schroot:///chroot-name) |
|
|
|
|
# specific schroot on localhost |
|
|
|
|
;; |
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
**copy/exec** |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
my_name="${0##*/}" |
|
|
|
|
mode="$1"; shift |
|
|
|
|
|
|
|
|
|
log() { |
|
|
|
|
# uncomment me for debugging |
|
|
|
|
#echo "$@" | logger -t "cdist-$my_name-$mode" |
|
|
|
|
: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
die() { |
|
|
|
|
echo "$@" >&2 |
|
|
|
|
exit 1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uri="$__target_host" |
|
|
|
|
|
|
|
|
|
scheme="${uri%%:*}"; rest="${uri#$scheme:}"; rest="${rest#//}" |
|
|
|
|
authority="${rest%%/*}"; rest="${rest#$authority}" |
|
|
|
|
path="${rest%\?*}"; rest="${rest#$path}" |
|
|
|
|
schroot_name="${path#/}" |
|
|
|
|
|
|
|
|
|
[ "$scheme" = "schroot" ] || die "Failed to parse scheme from __target_host ($__target_host). Expected 'schroot', got '$scheme'" |
|
|
|
|
[ -n "$schroot_name" ] || die "Failed to parse schroot name from __target_host: $__target_host" |
|
|
|
|
|
|
|
|
|
case "$authority" in |
|
|
|
|
'') |
|
|
|
|
# authority is empty, neither user nor host given |
|
|
|
|
user="" |
|
|
|
|
host="" |
|
|
|
|
;; |
|
|
|
|
*@*) |
|
|
|
|
# authority contains @, take user from authority |
|
|
|
|
user="${authority%@*}" |
|
|
|
|
host="${authority#*@}" |
|
|
|
|
;; |
|
|
|
|
*) |
|
|
|
|
# no user in authority, default to root |
|
|
|
|
user="root" |
|
|
|
|
host="$authority" |
|
|
|
|
;; |
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
log "mode: $mode" |
|
|
|
|
log "@: $@" |
|
|
|
|
log "uri: $uri" |
|
|
|
|
log "scheme: $scheme" |
|
|
|
|
log "authority: $authority" |
|
|
|
|
log "user: $user" |
|
|
|
|
log "host: $host" |
|
|
|
|
log "path: $path" |
|
|
|
|
log "schroot_name: $schroot_name" |
|
|
|
|
|
|
|
|
|
exec_prefix="" |
|
|
|
|
copy_prefix="" |
|
|
|
|
if [ -n "$host" ]; then |
|
|
|
|
# we are working on a remote host |
|
|
|
|
exec_prefix="ssh -o User=$user -q $host" |
|
|
|
|
copy_prefix="scp -o User=$user -q" |
|
|
|
|
copy_destination_prefix="$host:" |
|
|
|
|
else |
|
|
|
|
# working on local machine |
|
|
|
|
copy_prefix="cp" |
|
|
|
|
copy_destination_prefix="" |
|
|
|
|
fi |
|
|
|
|
log "exec_prefix: $exec_prefix" |
|
|
|
|
log "copy_prefix: $copy_prefix" |
|
|
|
|
log "copy_destination_prefix: $copy_destination_prefix" |
|
|
|
|
|
|
|
|
|
case "$mode" in |
|
|
|
|
exec) |
|
|
|
|
# In exec mode the first argument is the __target_host which we already got from env. Get rid of it. |
|
|
|
|
shift |
|
|
|
|
code="$exec_prefix schroot -c $schroot_name -- sh -c '$@'" |
|
|
|
|
;; |
|
|
|
|
copy) |
|
|
|
|
# get directory for given chroot_name |
|
|
|
|
schroot_directory="$($exec_prefix schroot -c $schroot_name --config | awk -F = '/directory=/ {print $2}')" |
|
|
|
|
[ -n "$schroot_directory" ] || die "Failed to retreive schroot directory for schroot: $schroot_name" |
|
|
|
|
log "schroot_directory: $schroot_directory" |
|
|
|
|
# prefix destination with chroot |
|
|
|
|
code="$copy_prefix $(echo "$@" | sed "s|$uri:|${copy_destination_prefix}${schroot_directory}|g")" |
|
|
|
|
;; |
|
|
|
|
*) die "Unknown mode: $mode";; |
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
log "code: $code" |
|
|
|
|
|
|
|
|
|
# Run the code |
|
|
|
|
$code |
|
|
|
|
|
|
|
|
|
log "-----" |
|
|
|
|
|
|
|
|
|
sudo |
|
|
|
|
~~~~ |
|
|
|
|
|
|
|
|
|
**copy** |
|
|
|
|
|
|
|
|
|
Use rsync over ssh to copy files. Uses the "--rsync-path" option |
|
|
|
|
to run the remote rsync instance with sudo. |
|
|
|
|
|
|
|
|
|
This command assumes your ssh configuration is already set up in ~/.ssh/config. |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-copy /path/to/this/script target_host |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
# For rsync to do the right thing, the source has to end with "/" if it is |
|
|
|
|
# a directory. The below preprocessor loop takes care of that. |
|
|
|
|
|
|
|
|
|
# second last argument is the source |
|
|
|
|
source_index=$(($#-1)) |
|
|
|
|
index=0 |
|
|
|
|
for arg in $@; do |
|
|
|
|
if [ $index -eq 0 ]; then |
|
|
|
|
# reset $@ |
|
|
|
|
set -- |
|
|
|
|
fi |
|
|
|
|
index=$((index+=1)) |
|
|
|
|
if [ $index -eq $source_index -a -d "$arg" ]; then |
|
|
|
|
arg="${arg%/}/" |
|
|
|
|
fi |
|
|
|
|
set -- "$@" "$arg" |
|
|
|
|
done |
|
|
|
|
|
|
|
|
|
rsync --copy-links --rsync-path="sudo rsync" -e 'ssh' "$@" |
|
|
|
|
|
|
|
|
|
**exec** |
|
|
|
|
|
|
|
|
|
Prefixes all remote commands with sudo. |
|
|
|
|
|
|
|
|
|
This command assumes your ssh configuration is already set up in ~/.ssh/config. |
|
|
|
|
|
|
|
|
|
Usage: cdist config --remote-exec "/path/to/this/script" target_host |
|
|
|
|
|
|
|
|
|
.. code-block:: sh |
|
|
|
|
|
|
|
|
|
host="$1"; shift |
|
|
|
|
ssh -q "$host" sudo sh -c \""$@"\" |
|
|
|
|