push
This commit is contained in:
commit
355d82c611
86
DOCS.md
Normal file
86
DOCS.md
Normal file
@ -0,0 +1,86 @@
|
||||
Use the Rsync plugin to synchronize files to remote hosts, and execute arbitrary commands on those hosts.
|
||||
|
||||
## Config
|
||||
The following parameters are used to configure the plugin:
|
||||
- **user** - user to log in as on the remote machines, defaults to `root`
|
||||
- **key** - private SSH key for the remote machines
|
||||
- **hosts** - hostnames or ip-addresses of the remote machines
|
||||
- **port** - port to connect to on the remote machines, defaults to `22`
|
||||
- **source** - source folder to synchronize from, defaults to `./`
|
||||
- **target** - target folder on remote machines to synchronize to
|
||||
- **include** - rsync include filter
|
||||
- **exclude** - rsync exclude filter
|
||||
- **recursive** - recursively synchronize, defaults to `false`
|
||||
- **delete** - delete target folder contents, defaults to `false`
|
||||
- **args** - instruct plugin to use these additional rsync CLI arguments, example: `"--blocking-io"`
|
||||
- **prescript** - list of commands to execute on remote machines before rsync occurs
|
||||
- **script** - list of commands to execute on remote machines after rsync occurs
|
||||
- **log_level** - ssh log level, defaults to quiet
|
||||
|
||||
It is highly recommended to put your private key into a secret (`rsync_key`) so it is not exposed to users. This can be done using the drone-cli:
|
||||
|
||||
```sh
|
||||
drone secret add \
|
||||
--repository your/repo \
|
||||
--name rsync_key \
|
||||
--data @./id_rsa \
|
||||
```
|
||||
|
||||
Add the secret to your `.drone.yml`:
|
||||
```yaml
|
||||
kind: pipeline
|
||||
|
||||
steps:
|
||||
- name: rsync
|
||||
image: drillster/drone-rsync
|
||||
settings:
|
||||
user: some-user
|
||||
key:
|
||||
from_secret: rsync_key
|
||||
hosts:
|
||||
- remote1
|
||||
source: ./dist
|
||||
target: ~/packages
|
||||
secrets: [ rsync_key ]
|
||||
```
|
||||
|
||||
See the [secret guides](https://docs.drone.io/user-guide/secrets/pre-repository/) for additional information on secrets.
|
||||
|
||||
## Examples
|
||||
```yaml
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: rsync
|
||||
image: drillster/drone-rsync
|
||||
settings:
|
||||
hosts:
|
||||
- remote1
|
||||
- remote2
|
||||
user:
|
||||
from_secret: rsync_user
|
||||
key:
|
||||
from_secret: rsync_key
|
||||
source: ./dist
|
||||
target: ~/packages
|
||||
include:
|
||||
- "app.tar.gz"
|
||||
- "app.tar.gz.md5"
|
||||
exclude:
|
||||
- "**.*"
|
||||
prescript:
|
||||
- cd ~/packages
|
||||
- md5sum -c app.tar.gz.md5
|
||||
- tar -xf app.tar.gz -C ~/app
|
||||
script:
|
||||
- cd ~/packages
|
||||
- md5sum -c app.tar.gz.md5
|
||||
- tar -xf app.tar.gz -C ~/app
|
||||
```
|
||||
|
||||
The example above illustrates a situation where an app package (`app.tar.gz`) will be deployed to 2 remote hosts (`remote1` and `remote2`). An md5 checksum will be deployed as well. After deploying, the md5 checksum is used to check the deployed package. If successful the package is extracted.
|
||||
|
||||
## Important
|
||||
The script passed to **script** will be executed on remote machines directly after rsync completes to deploy the files. It will be executed step by step until a command returns a non-zero exit-code. If this happens, the entire plugin will exit and fail the build.
|
||||
|
6
Dockerfile
Normal file
6
Dockerfile
Normal file
@ -0,0 +1,6 @@
|
||||
FROM alpine:latest
|
||||
|
||||
RUN apk add --no-cache --update ca-certificates bash openssh-client rsync
|
||||
COPY upload.sh /usr/local/
|
||||
|
||||
ENTRYPOINT ["/usr/local/upload.sh"]
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Drillster
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
30
README.md
Normal file
30
README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# drone-rsync
|
||||
[](https://hub.docker.com/r/drillster/drone-rsync/)
|
||||
|
||||
This is a pure Bash [Drone](https://github.com/drone/drone) >= 0.5 plugin to sync files to remote hosts.
|
||||
|
||||
For more information on how to use the plugin, please take a look at [the docs](https://github.com/Drillster/drone-rsync/blob/master/DOCS.md).
|
||||
|
||||
## Docker
|
||||
Build the docker image by running:
|
||||
|
||||
```bash
|
||||
docker build --rm=true -t drillster/drone-rsync .
|
||||
```
|
||||
|
||||
## Usage
|
||||
Execute from the working directory (assuming you have an SSH server running on 127.0.0.1:22):
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-e PLUGIN_KEY=$(cat some-private-key) \
|
||||
-e PLUGIN_HOSTS="127.0.0.1, 127.0.0.2, 127.0.0.3" \
|
||||
-e PLUGIN_PORTS="22, 23, 24" \
|
||||
-e PLUGIN_TARGET="./" \
|
||||
-e PLUGIN_PRESCRIPT="echo \"Prescript Done!\"" \
|
||||
-e PLUGIN_SCRIPT="echo \"Postscript Done!\"" \
|
||||
-e PLUGIN_ARGS="--blocking-io" \
|
||||
-v $(pwd):$(pwd) \
|
||||
-w $(pwd) \
|
||||
drillster/drone-rsync
|
||||
```
|
153
upload.sh
Executable file
153
upload.sh
Executable file
@ -0,0 +1,153 @@
|
||||
#!/bin/bash
|
||||
if [ -z "$PLUGIN_HOSTS" ]; then
|
||||
echo "Specify at least one host!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$PLUGIN_TARGET" ]; then
|
||||
echo "Specify a target!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEFAULT_PORT=$PLUGIN_PORT
|
||||
if [ -z "$PLUGIN_PORT" ]; then
|
||||
echo "Port not specified, using default port 22!"
|
||||
DEFAULT_PORT="22"
|
||||
fi
|
||||
|
||||
SOURCE=$PLUGIN_SOURCE
|
||||
if [ -z "$PLUGIN_SOURCE" ]; then
|
||||
echo "No source folder specified, using default './'"
|
||||
SOURCE="./"
|
||||
fi
|
||||
|
||||
USER=$RSYNC_USER
|
||||
if [ -z "$RSYNC_USER" ]; then
|
||||
if [ -z "$PLUGIN_USER" ]; then
|
||||
echo "No user specified, using root!"
|
||||
USER="root"
|
||||
else
|
||||
USER=$PLUGIN_USER
|
||||
fi
|
||||
fi
|
||||
|
||||
SSH_KEY=$RSYNC_KEY
|
||||
if [ -z "$RSYNC_KEY" ]; then
|
||||
if [ -z "$PLUGIN_KEY" ]; then
|
||||
echo "No private key specified!"
|
||||
exit 1
|
||||
fi
|
||||
SSH_KEY=$PLUGIN_KEY
|
||||
fi
|
||||
|
||||
if [ -z "$PLUGIN_ARGS" ]; then
|
||||
ARGS=
|
||||
else
|
||||
ARGS=$PLUGIN_ARGS
|
||||
fi
|
||||
|
||||
if [ -z "$PLUGIN_LOG_LEVEL" ]; then
|
||||
LOG_LEVEL=quiet
|
||||
else
|
||||
LOG_LEVEL=$PLUGIN_LOG_LEVEL
|
||||
fi
|
||||
|
||||
# Building rsync command
|
||||
expr="rsync -az $ARGS"
|
||||
|
||||
if [[ -n "$PLUGIN_RECURSIVE" && "$PLUGIN_RECURSIVE" == "true" ]]; then
|
||||
expr="$expr -r"
|
||||
fi
|
||||
|
||||
if [[ -n "$PLUGIN_DELETE" && "$PLUGIN_DELETE" == "true" ]]; then
|
||||
expr="$expr --del"
|
||||
fi
|
||||
|
||||
expr="$expr -e 'ssh -p %s -o UserKnownHostsFile=/dev/null -o LogLevel=$LOG_LEVEL -o StrictHostKeyChecking=no'"
|
||||
|
||||
# Include
|
||||
IFS=','; read -ra INCLUDE <<< "$PLUGIN_INCLUDE"
|
||||
for include in "${INCLUDE[@]}"; do
|
||||
expr="$expr --include=$include"
|
||||
done
|
||||
|
||||
# Exclude
|
||||
IFS=','; read -ra EXCLUDE <<< "$PLUGIN_EXCLUDE"
|
||||
for exclude in "${EXCLUDE[@]}"; do
|
||||
expr="$expr --exclude=$exclude"
|
||||
done
|
||||
|
||||
# Filter
|
||||
IFS=','; read -ra FILTER <<< "$PLUGIN_FILTER"
|
||||
for filter in "${FILTER[@]}"; do
|
||||
expr="$expr --filter=$filter"
|
||||
done
|
||||
|
||||
expr="$expr $SOURCE"
|
||||
|
||||
# Prepare SSH
|
||||
home="/root"
|
||||
|
||||
mkdir -p "$home/.ssh"
|
||||
|
||||
printf "StrictHostKeyChecking no\n" > "$home/.ssh/config"
|
||||
chmod 0700 "$home/.ssh/config"
|
||||
|
||||
keyfile="$home/.ssh/id_rsa"
|
||||
echo "$SSH_KEY" | grep -q "ssh-ed25519"
|
||||
if [ $? -eq 0 ]; then
|
||||
printf "Using ed25519 based key\n"
|
||||
keyfile="$home/.ssh/id_ed25519"
|
||||
fi
|
||||
echo "$SSH_KEY" | grep -q "ecdsa-"
|
||||
if [ $? -eq 0 ]; then
|
||||
printf "Using ecdsa based key\n"
|
||||
keyfile="$home/.ssh/id_ecdsa"
|
||||
fi
|
||||
echo "$SSH_KEY" > $keyfile
|
||||
chmod 0600 $keyfile
|
||||
|
||||
function join_with { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }
|
||||
|
||||
# Parse SSH precommands
|
||||
IFS=','; read -ra COMMANDS <<< "$PLUGIN_PRESCRIPT"
|
||||
prescript=$(join_with ' && ' "${COMMANDS[@]}")
|
||||
# Parse SSH postcommands
|
||||
IFS=','; read -ra COMMANDS <<< "$PLUGIN_SCRIPT"
|
||||
postscript=$(join_with ' && ' "${COMMANDS[@]}")
|
||||
|
||||
# Run rsync
|
||||
IFS=','; read -ra HOSTS <<< "$PLUGIN_HOSTS"
|
||||
IFS=','; read -ra PORTS <<< "$PLUGIN_PORTS"
|
||||
result=0
|
||||
for ((i=0; i < ${#HOSTS[@]}; i++))
|
||||
do
|
||||
HOST=${HOSTS[$i]}
|
||||
PORT=${PORTS[$i]}
|
||||
if [ -z $PORT ]
|
||||
then
|
||||
# Default Port 22
|
||||
PORT=$DEFAULT_PORT
|
||||
fi
|
||||
echo $(printf "%s" "$ $(printf "$expr" "$PORT") $USER@$HOST:$PLUGIN_TARGET ...")
|
||||
if [ -n "$PLUGIN_PRESCRIPT" ]; then
|
||||
echo $(printf "%s" "$ ssh -p $PORT $USER@$HOST ...")
|
||||
echo $(printf "%s" " > $prescript ...")
|
||||
eval "ssh -p $PORT $USER@$HOST '$prescript'"
|
||||
result=$(($result+$?))
|
||||
echo $(printf "%s" "$ ssh -p $PORT $USER@$HOST result: $?")
|
||||
if [ "$result" -gt "0" ]; then exit $result; fi
|
||||
fi
|
||||
eval "$(printf "$expr" "$PORT") $USER@$HOST:$PLUGIN_TARGET"
|
||||
result=$(($result+$?))
|
||||
if [ "$result" -gt "0" ]; then exit $result; fi
|
||||
if [ -n "$PLUGIN_SCRIPT" ]; then
|
||||
echo $(printf "%s" "$ ssh -p $PORT $USER@$HOST ...")
|
||||
echo $(printf "%s" " > $postscript ...")
|
||||
eval "ssh -p $PORT $USER@$HOST '$postscript'"
|
||||
result=$(($result+$?))
|
||||
echo $(printf "%s" "$ ssh -p $PORT $USER@$HOST result: $?")
|
||||
if [ "$result" -gt "0" ]; then exit $result; fi
|
||||
fi
|
||||
done
|
||||
exit $result
|
Loading…
x
Reference in New Issue
Block a user