Compare commits

...

51 Commits

Author SHA1 Message Date
Bo-Yi Wu 65e19227c4 update readme.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2017-01-02 21:26:26 +08:00
Bo-Yi Wu df18b64cb4 fix fmt command.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-31 13:30:36 +08:00
Bo-Yi Wu f987106211 support ssh agent.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-30 21:50:39 +08:00
Bo-Yi Wu eddd7a9661 [ci skip] remove windows support.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-30 15:12:36 +08:00
Bo-Yi Wu 1355c4edc1 [ci skip] add badge.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-30 13:36:39 +08:00
Bo-Yi Wu 2eb54a15ca remove create root .ssh folder.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-30 13:12:10 +08:00
Bo-Yi Wu 42540b5d45 Merge pull request #19 from appleboy/ssh
Add ssh testing.
2016-12-30 12:43:49 +08:00
Bo-Yi Wu 5f176416d7 add ssh server for alpine.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-30 12:38:44 +08:00
Bo-Yi Wu 6c2d597d31 update drone setting
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-30 11:33:57 +08:00
Bo-Yi Wu 9aa3cdb828 update travis testing.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-30 11:13:22 +08:00
Bo-Yi Wu 392c7c90e3 Add ssh testing.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-30 10:44:49 +08:00
Bo-Yi Wu a0c61bbd03 update readme.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-29 07:17:55 +08:00
Bo-Yi Wu 5a6851415d Support key path.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-29 07:16:38 +08:00
Bo-Yi Wu e4f3a180c8 add random string.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 15:56:17 +08:00
Bo-Yi Wu 9dbfdad07c remove ENV.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 14:58:51 +08:00
Bo-Yi Wu debd2db692 hide codecov token
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:54:13 +08:00
Bo-Yi Wu 5bd128025d add cache and fix repo name
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:52:36 +08:00
Bo-Yi Wu d3b4925aff add drone sign file.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:48:59 +08:00
Bo-Yi Wu 291c006b5c fix docker image name
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:45:05 +08:00
Bo-Yi Wu dd7f593c06 fix makefile.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:43:26 +08:00
Bo-Yi Wu 9559a5b600 Merge pull request #17 from appleboy/tool
Add release tool
2016-12-28 11:41:00 +08:00
Bo-Yi Wu 974cd420af add some env.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:27:23 +08:00
Bo-Yi Wu d31fe06287 add badge.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:25:35 +08:00
Bo-Yi Wu 9384d1261d add coverage command.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:23:06 +08:00
Bo-Yi Wu 43037f5cef using go latest version.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:15:49 +08:00
Bo-Yi Wu f43d0a817e remove docker from travis.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:14:56 +08:00
Bo-Yi Wu 6cb6510fed fix path.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:11:15 +08:00
Bo-Yi Wu da5dda1f0d update glide version.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:09:43 +08:00
Bo-Yi Wu 4fc0ebcd98 update tool
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-28 11:02:31 +08:00
Bo-Yi Wu e3418f8441 Merge pull request #15 from appleboy/sync
Support golang routines
2016-12-27 14:38:42 +08:00
Bo-Yi Wu d5baf6186d update readme.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-27 14:33:56 +08:00
Bo-Yi Wu f5d5e54a57 Support routines.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-27 14:33:21 +08:00
Bo-Yi Wu 031c1e4801 Merge pull request #13 from appleboy/multiple_target
support multiple target
2016-12-19 16:42:13 +08:00
Bo-Yi Wu 1bae57a838 update readme.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-19 16:30:41 +08:00
Bo-Yi Wu 91ef54d3d6 Support multiple target.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-19 16:29:38 +08:00
Bo-Yi Wu bfb8c6795c Merge pull request #12 from appleboy/multiple_host
support multiple host
2016-12-19 15:28:46 +08:00
Bo-Yi Wu 339a0d497f fix testing
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-19 15:23:16 +08:00
Bo-Yi Wu cc1520024e support multiple host
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-19 15:13:11 +08:00
Bo-Yi Wu 455b6dd7ae update check go version.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-05 11:19:52 +08:00
Bo-Yi Wu f12fc6e476 update golang testing to 1.6.4 and 1.7.4
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-05 11:12:08 +08:00
Bo-Yi Wu 807dff2951 update readme.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-05 11:10:21 +08:00
Bo-Yi Wu 8171197bad Merge pull request #10 from appleboy/rm
Support rm flag
2016-12-05 11:08:03 +08:00
Bo-Yi Wu 3277383d4f update readme
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-05 11:06:10 +08:00
Bo-Yi Wu 2bb7d842f2 support rm flag
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-12-05 11:04:11 +08:00
Bo-Yi Wu 6e7710e445 Merge pull request #6 from appleboy/bug
fix tar multiple folder or file.
2016-11-29 15:30:07 +08:00
Bo-Yi Wu 658203c26d fix tar multiple folder or file.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-11-29 15:29:03 +08:00
Bo-Yi Wu 7cd8855a53 remove --rm flag 2016-11-28 16:37:33 +08:00
Bo-Yi Wu 42851ed07b Merge pull request #4 from appleboy/cli
Support load configuration from files.
2016-11-21 11:19:36 +08:00
Bo-Yi Wu 7b90afbf37 Support load configuration from files.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-11-21 11:10:20 +08:00
Bo-Yi Wu 21d349362b update Version comment.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-11-19 22:34:54 +08:00
Bo-Yi Wu 7dfdbbde89 add version command.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-11-19 21:21:37 +08:00
17 changed files with 725 additions and 157 deletions
+84
View File
@@ -0,0 +1,84 @@
workspace:
base: /srv/app
path: src/github.com/appleboy/drone-scp
pipeline:
# restore the cache from an sftp server
restore_cache:
image: appleboy/drone-sftp-cache
restore: true
mount: [ .glide, vendor ]
ignore_branch: true
test:
image: appleboy/golang-testing
pull: true
environment:
TAGS: netgo
GOPATH: /srv/app
commands:
- adduser -h /home/drone-scp -s /bin/bash -D -S drone-scp
- passwd -d drone-scp
- mkdir -p /home/drone-scp/.ssh
- chmod 700 /home/drone-scp/.ssh
- cp tests/.ssh/id_rsa.pub /home/drone-scp/.ssh/authorized_keys
- chown -R drone-scp /home/drone-scp/.ssh
# install ssh and start server
- apk update && apk add openssh openrc
- rm -rf /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key
- ./tests/entrypoint.sh /usr/sbin/sshd -D &
- make dep_install
- make vet
- make lint
- make test
- make coverage
- make build
# build binary for docker image
- make static_build
when:
event: [ push, tag, pull_request ]
release:
image: appleboy/golang-testing
pull: true
environment:
TAGS: netgo
GOPATH: /srv/app
commands:
- make release
when:
event: [ tag ]
branch: [ refs/tags/* ]
docker:
image: plugins/docker
repo: ${DRONE_REPO}
tags: [ '${DRONE_TAG}' ]
when:
event: [ tag ]
branch: [ refs/tags/* ]
docker:
image: plugins/docker
repo: ${DRONE_REPO}
tags: [ 'latest' ]
when:
event: [ push ]
branch: [ master ]
github:
image: plugins/github-release
files:
- dist/release/*
when:
event: [ tag ]
branch: [ refs/tags/* ]
# rebuild the cache on the sftp server
rebuild_cache:
image: appleboy/drone-sftp-cache
rebuild: true
mount: [ .glide, vendor ]
ignore_branch: true
when:
branch: master
+1
View File
@@ -0,0 +1 @@
eyJhbGciOiJIUzI1NiJ9.d29ya3NwYWNlOgogIGJhc2U6IC9zcnYvYXBwCiAgcGF0aDogc3JjL2dpdGh1Yi5jb20vYXBwbGVib3kvZHJvbmUtc2NwCgpwaXBlbGluZToKICAjIHJlc3RvcmUgdGhlIGNhY2hlIGZyb20gYW4gc2Z0cCBzZXJ2ZXIKICByZXN0b3JlX2NhY2hlOgogICAgaW1hZ2U6IGFwcGxlYm95L2Ryb25lLXNmdHAtY2FjaGUKICAgIHJlc3RvcmU6IHRydWUKICAgIG1vdW50OiBbIC5nbGlkZSwgdmVuZG9yIF0KICAgIGlnbm9yZV9icmFuY2g6IHRydWUKCiAgdGVzdDoKICAgIGltYWdlOiBhcHBsZWJveS9nb2xhbmctdGVzdGluZwogICAgcHVsbDogdHJ1ZQogICAgZW52aXJvbm1lbnQ6CiAgICAgIFRBR1M6IG5ldGdvCiAgICAgIEdPUEFUSDogL3Nydi9hcHAKICAgIGNvbW1hbmRzOgogICAgICAtIGFkZHVzZXIgLWggL2hvbWUvZHJvbmUtc2NwIC1zIC9iaW4vYmFzaCAtRCAtUyBkcm9uZS1zY3AKICAgICAgLSBwYXNzd2QgLWQgZHJvbmUtc2NwCiAgICAgIC0gbWtkaXIgLXAgL2hvbWUvZHJvbmUtc2NwLy5zc2gKICAgICAgLSBjaG1vZCA3MDAgL2hvbWUvZHJvbmUtc2NwLy5zc2gKICAgICAgLSBjcCB0ZXN0cy8uc3NoL2lkX3JzYS5wdWIgL2hvbWUvZHJvbmUtc2NwLy5zc2gvYXV0aG9yaXplZF9rZXlzCiAgICAgIC0gY2hvd24gLVIgZHJvbmUtc2NwIC9ob21lL2Ryb25lLXNjcC8uc3NoCiAgICAgICMgaW5zdGFsbCBzc2ggYW5kIHN0YXJ0IHNlcnZlcgogICAgICAtIGFwayB1cGRhdGUgJiYgYXBrIGFkZCBvcGVuc3NoIG9wZW5yYwogICAgICAtIHJtIC1yZiAvZXRjL3NzaC9zc2hfaG9zdF9yc2Ffa2V5IC9ldGMvc3NoL3NzaF9ob3N0X2RzYV9rZXkKICAgICAgLSAuL3Rlc3RzL2VudHJ5cG9pbnQuc2ggL3Vzci9zYmluL3NzaGQgLUQgJgogICAgICAtIG1ha2UgZGVwX2luc3RhbGwKICAgICAgLSBtYWtlIHZldAogICAgICAtIG1ha2UgbGludAogICAgICAtIG1ha2UgdGVzdAogICAgICAtIG1ha2UgY292ZXJhZ2UKICAgICAgLSBtYWtlIGJ1aWxkCiAgICAgICMgYnVpbGQgYmluYXJ5IGZvciBkb2NrZXIgaW1hZ2UKICAgICAgLSBtYWtlIHN0YXRpY19idWlsZAogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCwgdGFnLCBwdWxsX3JlcXVlc3QgXQoKICByZWxlYXNlOgogICAgaW1hZ2U6IGFwcGxlYm95L2dvbGFuZy10ZXN0aW5nCiAgICBwdWxsOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgVEFHUzogbmV0Z28KICAgICAgR09QQVRIOiAvc3J2L2FwcAogICAgY29tbWFuZHM6CiAgICAgIC0gbWFrZSByZWxlYXNlCiAgICB3aGVuOgogICAgICBldmVudDogWyB0YWcgXQogICAgICBicmFuY2g6IFsgcmVmcy90YWdzLyogXQoKICBkb2NrZXI6CiAgICBpbWFnZTogcGx1Z2lucy9kb2NrZXIKICAgIHJlcG86ICR7RFJPTkVfUkVQT30KICAgIHRhZ3M6IFsgJyR7RFJPTkVfVEFHfScgXQogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgdGFnIF0KICAgICAgYnJhbmNoOiBbIHJlZnMvdGFncy8qIF0KCiAgZG9ja2VyOgogICAgaW1hZ2U6IHBsdWdpbnMvZG9ja2VyCiAgICByZXBvOiAke0RST05FX1JFUE99CiAgICB0YWdzOiBbICdsYXRlc3QnIF0KICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2ggXQogICAgICBicmFuY2g6IFsgbWFzdGVyIF0KCiAgZ2l0aHViOgogICAgaW1hZ2U6IHBsdWdpbnMvZ2l0aHViLXJlbGVhc2UKICAgIGZpbGVzOgogICAgICAtIGRpc3QvcmVsZWFzZS8qCiAgICB3aGVuOgogICAgICBldmVudDogWyB0YWcgXQogICAgICBicmFuY2g6IFsgcmVmcy90YWdzLyogXQoKICAjIHJlYnVpbGQgdGhlIGNhY2hlIG9uIHRoZSBzZnRwIHNlcnZlcgogIHJlYnVpbGRfY2FjaGU6CiAgICBpbWFnZTogYXBwbGVib3kvZHJvbmUtc2Z0cC1jYWNoZQogICAgcmVidWlsZDogdHJ1ZQogICAgbW91bnQ6IFsgLmdsaWRlLCB2ZW5kb3IgXQogICAgaWdub3JlX2JyYW5jaDogdHJ1ZQogICAgd2hlbjoKICAgICAgYnJhbmNoOiBtYXN0ZXIK.iJq2DIBtHk-IH2ioZdNEkFcxDj-5mtNikSX66Jdt_pM
+2
View File
@@ -25,3 +25,5 @@ _testmain.go
vendor
drone-scp
coverage.txt
.env
dist
+11 -34
View File
@@ -1,53 +1,30 @@
sudo: required
language: go
services:
- docker
go:
- 1.5.4
- 1.6.3
- 1.7.3
- 1.6.x
- 1.7.x
- tip
env:
global:
- DOCKER_CACHE_FILE=${HOME}/docker/cache.tar.gz
cache:
directories:
- vendor
- ${HOME}/.glide
- ${HOME}/docker
before_install:
- mkdir -p $GOPATH/bin
- curl https://glide.sh/get | sh
- if [ -f ${DOCKER_CACHE_FILE} ]; then gunzip -c ${DOCKER_CACHE_FILE} | docker load; fi
- sudo useradd -m -d /home/drone-scp -s /bin/bash drone-scp
- sudo mkdir -p /home/drone-scp/.ssh
- sudo chmod 700 /home/drone-scp/.ssh
- sudo cp tests/.ssh/id_rsa.pub /home/drone-scp/.ssh/authorized_keys
- sudo chown -R drone-scp /home/drone-scp/.ssh
install:
- export GO15VENDOREXPERIMENT=1
- make install
- make dep_install
script:
- make vet
- make lint
- make test
- make docker
- if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
mkdir -p $(dirname ${DOCKER_CACHE_FILE});
docker save $(docker history -q $TRAVIS_REPO_SLUG:latest | grep -v '<missing>') | gzip > ${DOCKER_CACHE_FILE};
fi
after_success:
# ignore main.go coverage
- sed -i '/main.go/d' coverage.txt
- bash <(curl -s https://codecov.io/bash) -f coverage.txt
# deploy from master
- if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_GO_VERSION" == "1.7.3" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD";
make docker_deploy tag=latest;
fi
# deploy from tag
- if [ "$TRAVIS_GO_VERSION" == "1.7.3" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD";
make docker_deploy tag=$TRAVIS_TAG;
fi
- make build
+84 -15
View File
@@ -1,8 +1,17 @@
.PHONY: install build test html update docker_build docker_image docker docker_deploy clean
.PHONY: test drone-scp build fmt vet errcheck lint install update release-dirs release-build release-copy release-check release coverage
VERSION := $(shell git describe --tags || git rev-parse --short HEAD)
DEPLOY_ACCOUNT := "appleboy"
DEPLOY_IMAGE := "drone-scp"
DIST := dist
EXECUTABLE := drone-scp
# for dockerhub
DEPLOY_ACCOUNT := appleboy
DEPLOY_IMAGE := $(EXECUTABLE)
TARGETS ?= linux darwin
PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
SOURCES ?= $(shell find . -name "*.go" -type f)
TAGS ?=
LDFLAGS += -X 'main.Version=$(VERSION)'
ifneq ($(shell uname), Darwin)
EXTLDFLAGS = -extldflags "-static" $(null)
@@ -10,36 +19,96 @@ else
EXTLDFLAGS =
endif
install:
glide install
ifneq ($(DRONE_TAG),)
VERSION ?= $(DRONE_TAG)
else
VERSION ?= $(shell git describe --tags --always || git rev-parse --short HEAD)
endif
build:
go build -ldflags="$(EXTLDFLAGS)-s -w -X main.Version=$(VERSION)"
all: build
fmt:
find . -name "*.go" -type f -not -path "./vendor/*" | xargs gofmt -s -w
vet:
go vet $(PACKAGES)
errcheck:
@which errcheck > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/kisielk/errcheck; \
fi
errcheck $(PACKAGES)
lint:
@which golint > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/golang/lint/golint; \
fi
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
test:
go test -v -coverprofile=coverage.txt
for PKG in $(PACKAGES); do go test -v -cover -coverprofile $$GOPATH/src/$$PKG/coverage.txt $$PKG || exit 1; done;
html:
go tool cover -html=coverage.txt
update:
dep_install:
glide install
dep_update:
glide up
docker_build:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo -ldflags="-X main.Version=$(VERSION)"
install: $(SOURCES)
go install -v -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)'
build: $(EXECUTABLE)
$(EXECUTABLE): $(SOURCES)
go build -v -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o $@
release: release-dirs release-build release-copy release-check
release-dirs:
mkdir -p $(DIST)/binaries $(DIST)/release
release-build:
@which gox > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/mitchellh/gox; \
fi
gox -os="$(TARGETS)" -arch="amd64 386" -tags="$(TAGS)" -ldflags="-s -w $(LDFLAGS)" -output="$(DIST)/binaries/$(EXECUTABLE)-$(VERSION)-{{.OS}}-{{.Arch}}"
release-copy:
$(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),cp $(file) $(DIST)/release/$(notdir $(file));)
release-check:
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
# for docker.
static_build:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o $(DEPLOY_IMAGE)
docker_image:
docker build --rm -t $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE) .
docker build -t $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE) .
docker: docker_build docker_image
docker: static_build docker_image
docker_deploy:
ifeq ($(tag),)
@echo "Usage: make $@ tag=<tag>"
@exit 1
endif
# deploy image
docker tag $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):latest $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):$(tag)
docker push $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):$(tag)
coverage:
sed -i '/main.go/d' coverage.txt
curl -s https://codecov.io/bash > .codecov && \
chmod +x .codecov && \
./.codecov -f coverage.txt
clean:
rm -rf coverage.txt ${DEPLOY_IMAGE}
go clean -x -i ./...
rm -rf coverage.txt $(EXECUTABLE) $(DIST) vendor
version:
@echo $(VERSION)
+183 -14
View File
@@ -1,25 +1,36 @@
# drone-scp
[![Build Status](https://travis-ci.org/appleboy/drone-scp.svg?branch=master)](https://travis-ci.org/appleboy/drone-scp) [![codecov](https://codecov.io/gh/appleboy/drone-scp/branch/master/graph/badge.svg)](https://codecov.io/gh/appleboy/drone-scp) [![Go Report Card](https://goreportcard.com/badge/github.com/appleboy/drone-scp)](https://goreportcard.com/report/github.com/appleboy/drone-scp)
[![GoDoc](https://godoc.org/github.com/appleboy/drone-scp?status.svg)](https://godoc.org/github.com/appleboy/drone-scp) [![Build Status](http://drone.wu-boy.com/api/badges/appleboy/drone-scp/status.svg)](http://drone.wu-boy.com/appleboy/drone-scp) [![codecov](https://codecov.io/gh/appleboy/drone-scp/branch/master/graph/badge.svg)](https://codecov.io/gh/appleboy/drone-scp) [![Go Report Card](https://goreportcard.com/badge/github.com/appleboy/drone-scp)](https://goreportcard.com/report/github.com/appleboy/drone-scp) [![Docker Pulls](https://img.shields.io/docker/pulls/appleboy/drone-scp.svg)](https://hub.docker.com/r/appleboy/drone-scp/) [![](https://images.microbadger.com/badges/image/appleboy/drone-scp.svg)](https://microbadger.com/images/appleboy/drone-scp "Get your own image badge on microbadger.com")
[Drone](https://github.com/drone/drone) plugin to copy files and artifacts via SSH.
## Build
## Feature
Build the binary with the following commands:
* [x] Support routines.
* [x] Support send files to multiple host.
* [x] Support send files to multiple target folder on host.
* [x] Support load ssh key from absolute path or raw body.
## Build or Download a binary
The pre-compiled binaries can be downloaded from [release page](https://github.com/appleboy/drone-scp/releases). Support the following OS type.
* Windows amd64/386
* Linux amd64/386
* Darwin amd64/386
With `Go` installed
```
$ go get -u -v github.com/appleboy/drone-scp
```
or build the binary with the following command:
```
$ make build
```
## Testing
Test the package with the following command:
```
$ make test
```
## Docker
Build the docker image with the following commands:
@@ -29,7 +40,7 @@ $ make docker
```
Please note incorrectly building the image for the correct x64 linux and with
GCO disabled will result in an error when running the Docker image:
CGO disabled will result in an error when running the Docker image:
```
docker: Error response from daemon: Container command
@@ -38,17 +49,167 @@ docker: Error response from daemon: Container command
## Usage
There are three ways to send notification.
* [usage from binary](#usage-from-binary)
* [usage from docker](#usage-from-docker)
* [usage from drone ci](#usage-from-drone-ci)
<a name="usage-from-binary"></a>
### Usage from binary
#### Using public key
```bash
drone-scp --host=example.com \
--port=22 \
--username=appleboy \
--key-path="${HOME}/.ssh/id_rsa" \
--target=/home/appleboy/test \
--source=your_local_folder_path
```
#### Using password
```diff
drone-scp --host=example.com \
--port=22 \
--username=appleboy \
+ --password=xxxxxxx \
--target=/home/appleboy/test \
--source=your_local_folder_path
```
#### Using ssh-agent
Start your local ssh agent:
```bash
eval `ssh-agent -s`
```
Import your local public key `~/.ssh/id_rsa`
```bash
$ ssh-add
```
You don't need to add `--password` or `--key-path` arguments.
```bash
drone-scp --host=example.com \
--port=22 \
--username=appleboy \
--target=/home/appleboy/test \
--source=your_local_folder_path
```
#### Send multiple source or target folder and hosts
```diff
drone-scp --host=example1.com \
+ --host=example2.com \
--port=22 \
--username=appleboy \
--password= xxxxxxx
--target=/home/appleboy/test1 \
+ --target=/home/appleboy/test2 \
--source=your_local_folder_path_1
+ --source=your_local_folder_path_2
```
<a name="usage-from-docker"></a>
### Usage from docker
#### Using public key
```bash
docker run --rm \
-e SCP_HOST=example.com \
-e SCP_USERNAME=xxxxxxx \
-e SCP_PORT=22 \
-e SCP_KEY_PATH="${HOME}/.ssh/id_rsa"
-e SCP_SOURCE=SOURCE_FILE_LIST \
-e SCP_TARGET=TARGET_FOLDER_PATH \
-v $(pwd):$(pwd) \
-w $(pwd) \
appleboy/drone-scp
```
#### Using password
```diff
docker run --rm \
-e SCP_HOST=example.com \
-e SCP_USERNAME=xxxxxxx \
-e SCP_PORT=22 \
+ -e SCP_PASSWORD="xxxxxxx"
-e SCP_SOURCE=SOURCE_FILE_LIST \
-e SCP_TARGET=TARGET_FOLDER_PATH \
-v $(pwd):$(pwd) \
-w $(pwd) \
appleboy/drone-scp
```
#### Using ssh-agent
Start your local ssh agent:
```bash
eval `ssh-agent -s`
```
Import your local public key `~/.ssh/id_rsa`
```bash
$ ssh-add
```
You don't need to add `SCP_PASSWORD` or `SCP_KEY_PATH ` arguments.
```bash
docker run --rm \
-e SCP_HOST=example.com \
-e SCP_USERNAME=xxxxxxx \
-e SCP_PORT=22 \
-e SCP_SOURCE=SOURCE_FILE_LIST \
-e SCP_TARGET=TARGET_FOLDER_PATH \
-v $(pwd):$(pwd) \
-w $(pwd) \
appleboy/drone-scp
```
#### Send multiple source or target folder and hosts
```bash
docker run --rm \
-e SCP_HOST=example1.com,example2.com \
-e SCP_USERNAME=xxxxxxx \
-e SCP_PASSWORD=xxxxxxx \
-e SCP_PORT=22 \
-e SCP_SOURCE=SOURCE_FILE_LIST_1,SOURCE_FILE_LIST_2 \
-e SCP_TARGET=TARGET_FOLDER_PATH_1,TARGET_FOLDER_PATH_2 \
-v $(pwd):$(pwd) \
-w $(pwd) \
appleboy/drone-scp
```
<a name="usage-from-drone-ci"></a>
### Usage from drone ci
Execute from the working directory:
```
```bash
docker run --rm \
-e PLUGIN_HOST=http://example.com \
-e PLUGIN_HOST=example.com \
-e PLUGIN_USERNAME=xxxxxxx \
-e PLUGIN_PASSWORD=xxxxxxx \
-e PLUGIN_PORT=xxxxxxx \
-e PLUGIN_KEY="$(cat ${HOME}/.ssh/id_rsa)"
-e PLUGIN_SOURCE=SOURCE_FILE_LIST \
-e PLUGIN_TARGET=TARGET_FOLDER_PATH \
-e PLUGIN_RM=false \
-e PLUGIN_DEBUG=false \
-e DRONE_REPO_OWNER=appleboy \
-e DRONE_REPO_NAME=go-hello \
-e DRONE_COMMIT_SHA=e5e82b5eb3737205c25955dcc3dcacc839b7be52 \
@@ -61,3 +222,11 @@ docker run --rm \
-w $(pwd) \
appleboy/drone-scp
```
## Testing
Test the package with the following command:
```
$ make test
```
+26 -2
View File
@@ -8,6 +8,7 @@ import (
"bufio"
"fmt"
"io"
"io/ioutil"
"net"
"os"
"path/filepath"
@@ -16,7 +17,7 @@ import (
"golang.org/x/crypto/ssh/agent"
)
// Contains main authority information.
// MakeConfig Contains main authority information.
// User field should be a name of user on remote server (ex. john in ssh john@example.com).
// Server field should be a remote machine address (ex. example.com in ssh john@example.com)
// Key is a path to private key on your local machine.
@@ -27,10 +28,27 @@ type MakeConfig struct {
User string
Server string
Key string
KeyPath string
Port string
Password string
}
// returns ssh.Signer from user you running app home path + cutted key path.
// (ex. pubkey,err := getKeyFile("/.ssh/id_rsa") )
func getKeyFile(keypath string) (ssh.Signer, error) {
buf, err := ioutil.ReadFile(keypath)
if err != nil {
return nil, err
}
pubkey, err := ssh.ParsePrivateKey(buf)
if err != nil {
return nil, err
}
return pubkey, nil
}
// connects to remote server using MakeConfig struct and returns *ssh.Session
func (ssh_conf *MakeConfig) connect() (*ssh.Session, error) {
// auths holds the detected ssh auth methods
@@ -46,6 +64,12 @@ func (ssh_conf *MakeConfig) connect() (*ssh.Session, error) {
defer sshAgent.Close()
}
if ssh_conf.KeyPath != "" {
if pubkey, err := getKeyFile(ssh_conf.KeyPath); err == nil {
auths = append(auths, ssh.PublicKeys(pubkey))
}
}
if ssh_conf.Key != "" {
signer, _ := ssh.ParsePrivateKey([]byte(ssh_conf.Key))
auths = append(auths, ssh.PublicKeys(signer))
@@ -107,7 +131,7 @@ func (ssh_conf *MakeConfig) Stream(command string) (output chan string, done cha
return outputChan, done, err
}
// Runs command on remote machine and returns its stdout as a string
// Run command on remote machine and returns its stdout as a string
func (ssh_conf *MakeConfig) Run(command string) (outStr string, err error) {
outChan, doneChan, err := ssh_conf.Stream(command)
if err != nil {
Generated
+12 -8
View File
@@ -1,20 +1,24 @@
hash: d4830515599820a37217ef2806e6f9a3e7be66a417c46bb515fdae02b2e3b830
updated: 2016-10-19T16:23:55.991113936+08:00
hash: 324c76f4ece1989f584ec84aab8252020da4dcbc20e38990465a9a0b7400f8ec
updated: 2016-12-28T15:52:54.896825557+08:00
imports:
- name: github.com/appleboy/com
version: c2e1fea1b771a26cb55774843ebd8955d723ee4e
subpackages:
- random
- name: github.com/joho/godotenv
version: 4ed13390c0acd2ff4e371e64d8b97c8954138243
version: a01a834e1654b4c9ca5b3ad05159445cc9c7ad08
subpackages:
- autoload
- name: github.com/urfave/cli
version: 55f715e28c46073d0e217e2ce8eb46b0b45e3db6
version: 0bdeddeeb0f650497d603c4ad7b20cfe685682f6
- name: golang.org/x/crypto
version: c367d6eeb7c6158125f2f47e049f7eb7e251c09a
version: c2f4947f41766b144bb09066e919466da5eddeae
subpackages:
- ssh
- ssh/agent
- curve25519
- ed25519
- ed25519/internal/edwards25519
- ssh
- ssh/agent
testImports:
- name: github.com/davecgh/go-spew
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
@@ -25,6 +29,6 @@ testImports:
subpackages:
- difflib
- name: github.com/stretchr/testify
version: 976c720a22c8eb4eb6a0b4348ad85ad12491a506
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
subpackages:
- assert
+6
View File
@@ -1,14 +1,20 @@
package: github.com/appleboy/drone-scp
import:
- package: github.com/joho/godotenv
version: ^1.0.0
subpackages:
- autoload
- package: github.com/urfave/cli
version: ^1.19.1
- package: golang.org/x/crypto
subpackages:
- ssh
- ssh/agent
- package: github.com/appleboy/com
subpackages:
- random
testImport:
- package: github.com/stretchr/testify
version: ^1.1.4
subpackages:
- assert
+34 -15
View File
@@ -2,22 +2,28 @@ package main
import (
"os"
"runtime"
"github.com/joho/godotenv"
_ "github.com/joho/godotenv/autoload"
"github.com/urfave/cli"
)
// Version for command line
var Version string
// Version set at compile-time
var Version = "v1.0.0-dev"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
}
func main() {
app := cli.NewApp()
app.Name = "telegram plugin"
app.Usage = "telegram plugin"
app.Name = "scp plugin"
app.Usage = "scp plugin"
app.Action = run
app.Version = Version
app.Flags = []cli.Flag{
cli.StringFlag{
cli.StringSliceFlag{
Name: "host",
Usage: "Server host",
EnvVar: "PLUGIN_HOST,SCP_HOST",
@@ -44,20 +50,24 @@ func main() {
EnvVar: "PLUGIN_KEY,SCP_KEY",
},
cli.StringFlag{
Name: "key-path",
Usage: "ssh private key path",
EnvVar: "PLUGIN_KEY_PATH,SCP_KEY_PATH",
},
cli.StringSliceFlag{
Name: "target",
Value: "/",
Usage: "Target path on the server, default to '/'",
EnvVar: "PLUGIN_TARGET",
Usage: "Target path on the server",
EnvVar: "PLUGIN_TARGET,SCP_TARGET",
},
cli.StringSliceFlag{
Name: "source",
Usage: "scp file list",
EnvVar: "PLUGIN_SOURCE",
EnvVar: "PLUGIN_SOURCE,SCP_SOURCE",
},
cli.BoolFlag{
Name: "debug",
Usage: "display message from command",
EnvVar: "PLUGIN_DEBUG",
Name: "rm",
Usage: "remove target folder before upload data",
EnvVar: "PLUGIN_RM,SCP_RM",
},
cli.StringFlag{
Name: "repo.owner",
@@ -112,11 +122,19 @@ func main() {
Usage: "build link",
EnvVar: "DRONE_BUILD_LINK",
},
cli.StringFlag{
Name: "env-file",
Usage: "source env file",
},
}
app.Run(os.Args)
}
func run(c *cli.Context) error {
if c.String("env-file") != "" {
_ = godotenv.Load(c.String("env-file"))
}
plugin := Plugin{
Repo: Repo{
Owner: c.String("repo.owner"),
@@ -133,14 +151,15 @@ func run(c *cli.Context) error {
Link: c.String("build.link"),
},
Config: Config{
Host: c.String("host"),
Host: c.StringSlice("host"),
Port: c.String("port"),
Username: c.String("username"),
Password: c.String("password"),
Key: c.String("key"),
Target: c.String("target"),
KeyPath: c.String("key-path"),
Target: c.StringSlice("target"),
Source: c.StringSlice("source"),
Debug: c.Bool("debug"),
Remove: c.Bool("rm"),
},
}
+95 -66
View File
@@ -9,7 +9,9 @@ import (
"os/exec"
"path/filepath"
"strings"
"sync"
"github.com/appleboy/com/random"
"github.com/appleboy/drone-scp/easyssh"
)
@@ -34,14 +36,15 @@ type (
// Config for the plugin.
Config struct {
Host string
Host []string
Port string
Username string
Password string
Key string
Target string
KeyPath string
Target []string
Source []string
Debug bool
Remove bool
}
// Plugin values.
@@ -52,6 +55,8 @@ type (
}
)
var wg sync.WaitGroup
func trimPath(keys []string) []string {
var newKeys []string
@@ -67,24 +72,23 @@ func trimPath(keys []string) []string {
return newKeys
}
func (p Plugin) log(host string, message ...interface{}) {
log.Printf("%s: %s", host, fmt.Sprintln(message...))
}
// Exec executes the plugin.
func (p Plugin) Exec() error {
if len(p.Config.Host) == 0 || len(p.Config.Username) == 0 || (len(p.Config.Password) == 0 && len(p.Config.Key) == 0) {
log.Println("missing ssh config (Host, Username, Password or Key)")
return errors.New("missing ssh config (Host, Username, Password or Key)")
if len(p.Config.Host) == 0 || len(p.Config.Username) == 0 {
return errors.New("missing ssh config (Host, Username)")
}
if len(p.Config.Source) == 0 {
log.Println("missing source file list config")
return errors.New("missing source file list config")
if len(p.Config.Source) == 0 || len(p.Config.Target) == 0 {
return errors.New("missing source or target config")
}
files := trimPath(p.Config.Source)
src := strings.Join(files, " ")
dest := fmt.Sprintf("%s-%s.tar", p.Repo.Name, p.Build.Commit[:7])
dest := fmt.Sprintf("%s.tar", random.String(10))
// create a temporary file for the archive
dir, err := ioutil.TempDir("", "")
@@ -95,70 +99,95 @@ func (p Plugin) Exec() error {
// run archive command
log.Println("tar all files into " + tar)
cmd := exec.Command("tar", "-cf", tar, src)
args := append(append([]string{}, "-cf", tar), files...)
cmd := exec.Command("tar", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
// Create MakeConfig instance with remote username, server address and path to private key.
ssh := &easyssh.MakeConfig{
Server: p.Config.Host,
User: p.Config.Username,
Password: p.Config.Password,
Port: p.Config.Port,
Key: p.Config.Key,
wg.Add(len(p.Config.Host))
errChannel := make(chan error, 1)
finished := make(chan bool, 1)
for _, host := range p.Config.Host {
go func(host string) {
// Create MakeConfig instance with remote username, server address and path to private key.
ssh := &easyssh.MakeConfig{
Server: host,
User: p.Config.Username,
Password: p.Config.Password,
Port: p.Config.Port,
Key: p.Config.Key,
KeyPath: p.Config.KeyPath,
}
// Call Scp method with file you want to upload to remote server.
p.log(host, "scp file to server.")
err = ssh.Scp(tar)
// Handle errors
if err != nil {
errChannel <- err
}
for _, target := range p.Config.Target {
// remove target before upload data
if p.Config.Remove {
p.log(host, "Remove target folder:", target)
_, err := ssh.Run(fmt.Sprintf("rm -rf %s", target))
if err != nil {
errChannel <- err
}
}
// mkdir path
p.log(host, "create folder", target)
response, _ := ssh.Run(fmt.Sprintf("mkdir -p %s", target))
if response != "" {
errChannel <- errors.New(response)
}
// untar file
p.log(host, "untar file", dest)
_, err = ssh.Run(fmt.Sprintf("tar -xf %s -C %s", dest, target))
if err != nil {
errChannel <- err
}
}
// remove tar file
p.log(host, "remove file", dest)
_, err = ssh.Run(fmt.Sprintf("rm -rf %s", dest))
if err != nil {
errChannel <- err
}
wg.Done()
}(host)
}
// Call Scp method with file you want to upload to remote server.
log.Println("scp file to remote server remote server.")
err = ssh.Scp(tar)
go func() {
wg.Wait()
close(finished)
}()
// Handle errors
if err != nil {
log.Println(err.Error())
return err
select {
case <-finished:
case err := <-errChannel:
if err != nil {
fmt.Println("drone-scp error: ", err)
return err
}
}
// mkdir path
log.Println("create remote folder " + p.Config.Target)
response, err := ssh.Run(fmt.Sprintf("mkdir -p %s", p.Config.Target))
if p.Config.Debug {
log.Println(response)
}
if err != nil {
log.Println(err.Error())
return err
}
// untar file
log.Println("untar remote file " + dest)
response, err = ssh.Run(fmt.Sprintf("tar -xf %s -C %s", dest, p.Config.Target))
if p.Config.Debug {
log.Println(response)
}
if err != nil {
log.Println(err.Error())
return err
}
// remove tar file
log.Println("remove remote file " + dest)
response, err = ssh.Run(fmt.Sprintf("rm -rf %s", dest))
if p.Config.Debug {
log.Println(response)
}
if err != nil {
log.Println(err.Error())
return err
}
fmt.Println("Successfully executed transfer data to all host.")
return nil
}
+146 -3
View File
@@ -3,10 +3,13 @@ package main
import (
"github.com/stretchr/testify/assert"
"os"
"os/exec"
"os/user"
"testing"
)
func TestMissingConfig(t *testing.T) {
func TestMissingAllConfig(t *testing.T) {
var plugin Plugin
err := plugin.Exec()
@@ -17,7 +20,7 @@ func TestMissingConfig(t *testing.T) {
func TestMissingSSHConfig(t *testing.T) {
plugin := Plugin{
Config: Config{
Host: "example.com",
Host: []string{"example.com"},
Username: "ubuntu",
},
}
@@ -30,7 +33,7 @@ func TestMissingSSHConfig(t *testing.T) {
func TestMissingSourceConfig(t *testing.T) {
plugin := Plugin{
Config: Config{
Host: "example.com",
Host: []string{"example.com"},
Username: "ubuntu",
Port: "443",
Password: "1234",
@@ -55,3 +58,143 @@ func TestTrimElement(t *testing.T) {
assert.Equal(t, result, trimPath(input))
}
func TestSCPFileFromPublicKey(t *testing.T) {
if os.Getenv("SSH_AUTH_SOCK") != "" {
exec.Command("eval", "`ssh-agent -k`").Run()
}
u, err := user.Lookup("drone-scp")
if err != nil {
t.Fatalf("Lookup: %v", err)
}
plugin := Plugin{
Config: Config{
Host: []string{"localhost"},
Username: "drone-scp",
Port: "22",
KeyPath: "tests/.ssh/id_rsa",
Source: []string{"tests/a.txt", "tests/b.txt"},
Target: []string{u.HomeDir + "/test"},
},
}
err = plugin.Exec()
assert.Nil(t, err)
// check file exist
if _, err := os.Stat(u.HomeDir + "/test/tests/a.txt"); os.IsNotExist(err) {
t.Fatalf("SCP-error: %v", err)
}
if _, err := os.Stat(u.HomeDir + "/test/tests/b.txt"); os.IsNotExist(err) {
t.Fatalf("SCP-error: %v", err)
}
// Test -rm flag
plugin.Config.Source = []string{"tests/a.txt"}
plugin.Config.Remove = true
err = plugin.Exec()
assert.Nil(t, err)
// check file exist
if _, err := os.Stat(u.HomeDir + "/test/tests/b.txt"); os.IsExist(err) {
t.Fatalf("SCP-error: %v", err)
}
}
// func TestSCPFileFromSSHAgent(t *testing.T) {
// if os.Getenv("SSH_AUTH_SOCK") == "" {
// exec.Command("eval", "`ssh-agent -s`").Run()
// exec.Command("ssh-add", "tests/.ssh/id_rsa").Run()
// }
// u, err := user.Lookup("drone-scp")
// if err != nil {
// t.Fatalf("Lookup: %v", err)
// }
// plugin := Plugin{
// Config: Config{
// Host: []string{"localhost"},
// Username: "drone-scp",
// Port: "22",
// Source: []string{"tests/a.txt", "tests/b.txt"},
// Target: []string{u.HomeDir + "/test"},
// },
// }
// err = plugin.Exec()
// assert.Nil(t, err)
// }
// func TestSCPFileFromPassword(t *testing.T) {
// u, err := user.Lookup("drone-scp")
// if err != nil {
// t.Fatalf("Lookup: %v", err)
// }
// plugin := Plugin{
// Config: Config{
// Host: []string{"localhost"},
// Username: "drone-scp",
// Port: "22",
// Password: "1234",
// Source: []string{"tests/a.txt", "tests/b.txt"},
// Target: []string{u.HomeDir + "/test"},
// },
// }
// err = plugin.Exec()
// assert.Nil(t, err)
// }
func TestIncorrectPassword(t *testing.T) {
plugin := Plugin{
Config: Config{
Host: []string{"localhost"},
Username: "drone-scp",
Port: "22",
Password: "123456",
Source: []string{"tests/a.txt", "tests/b.txt"},
Target: []string{"/home"},
},
}
err := plugin.Exec()
assert.NotNil(t, err)
}
func TestNoPermissionCreateFolder(t *testing.T) {
plugin := Plugin{
Config: Config{
Host: []string{"localhost"},
Username: "drone-scp",
Port: "22",
KeyPath: "tests/.ssh/id_rsa",
Source: []string{"tests/a.txt", "tests/b.txt"},
Target: []string{"/etc/test"},
},
}
err := plugin.Exec()
assert.NotNil(t, err)
}
func TestSourceNotFound(t *testing.T) {
plugin := Plugin{
Config: Config{
Host: []string{"localhost"},
Username: "drone-scp",
Port: "22",
KeyPath: "tests/.ssh/id_rsa",
Source: []string{"tests/aa.txt", "tests/b.txt"},
Target: []string{"/test"},
},
}
err := plugin.Exec()
assert.NotNil(t, err)
}
+27
View File
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA4e2D/qPN08pzTac+a8ZmlP1ziJOXk45CynMPtva0rtK/RB26
VbfAF0hIJji7ltvnYnqCU9oFfvEM33cTn7T96+od8ib/Vz25YU8ZbstqtIskPuwC
bv3K0mAHgsviJyRD7yM+QKTbBQEgbGuW6gtbMKhiYfiIB4Dyj7AdS/fk3v26wDgz
7SHI5OBqu9bv1KhxQYdFEnU3PAtAqeccgzNpbH3eYLyGzuUxEIJlhpZ/uU2G9ppj
/cSrONVPiI8Ahi4RrlZjmP5l57/sq1ClGulyLpFcMw68kP5FikyqHpHJHRBNgU57
1y0Ph33SjBbs0haCIAcmreWEhGe+/OXnJe6VUQIDAQABAoIBAH97emORIm9DaVSD
7mD6DqA7c5m5Tmpgd6eszU08YC/Vkz9oVuBPUwDQNIX8tT0m0KVs42VVPIyoj874
bgZMJoucC1G8V5Bur9AMxhkShx9g9A7dNXJTmsKilRpk2TOk7wBdLp9jZoKoZBdJ
jlp6FfaazQjjKD6zsCsMATwAoRCBpBNsmT6QDN0n0bIgY0tE6YGQaDdka0dAv68G
R0VZrcJ9voT6+f+rgJLoojn2DAu6iXaM99Gv8FK91YCymbQlXXgrk6CyS0IHexN7
V7a3k767KnRbrkqd3o6JyNun/CrUjQwHs1IQH34tvkWScbseRaFehcAm6mLT93RP
muauvMECgYEA9AXGtfDMse0FhvDPZx4mx8x+vcfsLvDHcDLkf/lbyPpu97C27b/z
ia07bu5TAXesUZrWZtKA5KeRE5doQSdTOv1N28BEr8ZwzDJwfn0DPUYUOxsN2iIy
MheO5A45Ko7bjKJVkZ61Mb1UxtqCTF9mqu9R3PBdJGthWOd+HUvF460CgYEA7QRf
Z8+vpGA+eSuu29e0xgRKnRzed5zXYpcI4aERc3JzBgO4Z0er9G8l66OWVGdMfpe6
CBajC5ToIiT8zqoYxXwqJgN+glir4gJe3mm8J703QfArZiQrdk0NTi5bY7+vLLG/
knTrtpdsKih6r3kjhuPPaAsIwmMxIydFvATKjLUCgYEAh/y4EihRSk5WKC8GxeZt
oiZ58vT4z+fqnMIfyJmD5up48JuQNcokw/LADj/ODiFM7GUnWkGxBrvDA3H67WQm
49bJjs8E+BfUQFdTjYnJRlpJZ+7Zt1gbNQMf5ENw5CCchTDqEq6pN0DVf8PBnSIF
KvkXW9KvdV5J76uCAn15mDkCgYA1y8dHzbjlCz9Cy2pt1aDfTPwOew33gi7U3skS
RTerx29aDyAcuQTLfyrROBkX4TZYiWGdEl5Bc7PYhCKpWawzrsH2TNa7CRtCOh2E
R+V/84+GNNf04ALJYCXD9/ugQVKmR1XfDRCvKeFQFE38Y/dvV2etCswbKt5tRy2p
xkCe/QKBgQCkLqafD4S20YHf6WTp3jp/4H/qEy2X2a8gdVVBi1uKkGDXr0n+AoVU
ib4KbP5ovZlrjL++akMQ7V2fHzuQIFWnCkDA5c2ZAqzlM+ZN+HRG7gWur7Bt4XH1
7XC9wlRna4b3Ln8ew3q1ZcBjXwD4ppbTlmwAfQIaZTGJUgQbdsO9YA==
-----END RSA PRIVATE KEY-----
+1
View File
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDh7YP+o83TynNNpz5rxmaU/XOIk5eTjkLKcw+29rSu0r9EHbpVt8AXSEgmOLuW2+dieoJT2gV+8QzfdxOftP3r6h3yJv9XPblhTxluy2q0iyQ+7AJu/crSYAeCy+InJEPvIz5ApNsFASBsa5bqC1swqGJh+IgHgPKPsB1L9+Te/brAODPtIcjk4Gq71u/UqHFBh0USdTc8C0Cp5xyDM2lsfd5gvIbO5TEQgmWGln+5TYb2mmP9xKs41U+IjwCGLhGuVmOY/mXnv+yrUKUa6XIukVwzDryQ/kWKTKoekckdEE2BTnvXLQ+HfdKMFuzSFoIgByat5YSEZ7785ecl7pVR drone-scp@localhost
View File
View File
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
if [ ! -f "/etc/ssh/ssh_host_rsa_key" ]; then
# generate fresh rsa key
ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa
fi
if [ ! -f "/etc/ssh/ssh_host_dsa_key" ]; then
# generate fresh dsa key
ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa
fi
exec "$@"