Merge branch 'docs/custom-remote-exec-copy-examples' into 'master'
Add custom remote copy/exec examples See merge request ungleich-public/cdist!938
This commit is contained in:
		
				commit
				
					
						84ade29ca9
					
				
			
		
					 1 changed files with 388 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -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 \""$@"\"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue