Start Up is a simple deployment tool that performs given set of commands on multiple hosts in parallel.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
小红帽 1768d1d243 更新gitignore文件 3 weeks ago
cmd/stup 增加了密码登录和自定义密钥路径的配置 3 weeks ago
docs init v1 version 4 weeks ago
example init v1 version 4 weeks ago
vssh 增加了密码登录和自定义密钥路径的配置 3 weeks ago
.gitignore 更新gitignore文件 3 weeks ago
LICENSE 更新gitignore文件 3 weeks ago
Makefile init v1 version 4 weeks ago
README.md 更新gitignore文件 3 weeks ago
client.go init v1 version 4 weeks ago
colors.go init v1 version 4 weeks ago
executor.go 增加了密码登录和自定义密钥路径的配置 3 weeks ago
go.mod init v1 version 4 weeks ago
go.sum init v1 version 4 weeks ago
localclient.go 增加了密码登录和自定义密钥路径的配置 3 weeks ago
sshclient.go 增加了密码登录和自定义密钥路径的配置 3 weeks ago
stup.go 增加了密码登录和自定义密钥路径的配置 3 weeks ago
stupfile.go 增加了密码登录和自定义密钥路径的配置 3 weeks ago
tar.go init v1 version 4 weeks ago
task.go init v1 version 4 weeks ago
version.go 增加了密码登录和自定义密钥路径的配置 3 weeks ago

README.md

Start Up

Start Up is a simple deployment tool that performs given set of commands on multiple hosts in parallel. It reads Stupfile, a YAML configuration file, which defines networks (groups of hosts), commands and targets.

Installation

$ make dist

Usage

$ stup [OPTIONS] NETWORK COMMAND [...]

Options

Option Description
-f Stupfile Custom path to Stupfile
-e, --env=[] Set environment variables
--only REGEXP Filter hosts matching regexp
--except REGEXP Filter out hosts matching regexp
--debug, -D Enable debug/verbose mode
--disable-prefix Disable hostname prefix
--help, -h Show help/usage
--version, -v Print version

Network

A group of hosts.

# Stupfile

networks:
    production:
        hosts:
            - api1.example.com
            - api2.example.com
            - api3.example.com
    staging:
        # fetch dynamic list of hosts
        inventory: curl http://example.com/latest/meta-data/hostname

$ stup production COMMAND will run COMMAND on api1, api2 and api3 hosts in parallel.

Command

A shell command(s) to be run remotely.

# Stupfile

commands:
    restart:
        desc: Restart example Docker container
        run: sudo docker restart example
    tail-logs:
        desc: Watch tail of Docker logs from all hosts
        run: sudo docker logs --tail=20 -f example

$ stup staging restart will restart all staging Docker containers in parallel.

$ stup production tail-logs will tail Docker logs from all production containers in parallel.

Serial command (a.k.a. Rolling Update)

serial: N constraints a command to be run on N hosts at a time at maximum. Rolling Update for free!

# Stupfile

commands:
    restart:
        desc: Restart example Docker container
        run: sudo docker restart example
        serial: 2

$ stup production restart will restart all Docker containers, two at a time at maximum.

Once command (one host only)

once: true constraints a command to be run only on one host. Useful for one-time tasks.

# Stupfile

commands:
    build:
        desc: Build Docker image and push to registry
        run: sudo docker build -t image:latest . && sudo docker push image:latest
        once: true # one host only
    pull:
        desc: Pull latest Docker image from registry
        run: sudo docker pull image:latest

$ stup production build pull will build Docker image on one production host only and spread it to all hosts.

Local command

Runs command always on localhost.

# Stupfile

commands:
    prepare:
        desc: Prepare to upload
        local: npm run build

Upload command

Uploads files/directories to all remote hosts. Uses tar under the hood.

# Stupfile

commands:
    upload:
        desc: Upload dist files to all hosts
        upload:
          - src: ./dist
            dst: /tmp/

Interactive Bash on all hosts

Do you want to interact with multiple hosts at once? Sure!

# Stupfile

commands:
    bash:
        desc: Interactive Bash on all hosts
        stdin: true
        run: bash
$ stup production bash
#
# type in commands and see output from all hosts!
# ^C

Passing prepared commands to all hosts:

$ echo 'sudo apt-get update -y' | stup production bash

# or:
$ stup production bash <<< 'sudo apt-get update -y'

# or:
$ cat <<EOF | stup production bash
sudo apt-get update -y
date
uname -a
EOF

Interactive Docker Exec on all hosts

# Stupfile

commands:
    exec:
        desc: Exec into Docker container on all hosts
        stdin: true
        run: sudo docker exec -i $CONTAINER bash
$ stup production exec
ps aux
strace -p 1 # trace system calls and signals on all your production hosts

Target

Target is an alias for multiple commands. Each command will be run on all hosts in parallel, stup will check return status from all hosts, and run subsequent commands on success only (thus any error on any host will interrupt the process).

# Stupfile

targets:
    deploy:
        - build
        - pull
        - migrate-db-up
        - stop-rm-run
        - health
        - slack-notify

$ stup production deploy

is equivalent to

$ stup production build pull migrate-db-up stop-rm-run health slack-notify airbrake-notify

Stupfile

See example Stupfile.

Basic structure

# Stupfile
---
version: 1

# Global environment variables
env:
  NAME: api
  IMAGE: example/api

networks:
  local:
    hosts:
      - address: localhost
  staging:
    hosts:
      - address: stg1.example.com
  production:
    hosts:
      - address: api1.example.com
      - address: api2.example.com
    user: ec2-user
    sudo: true

commands:
  echo:
    desc: Print some env vars
    run: echo $NAME $IMAGE $STUP_NETWORK
  date:
    desc: Print OS name and current date/time
    run: uname -a; date

targets:
  all:
    - echo
    - date

Default environment variables available in Stupfile

  • $STUP_HOST - Current host.
  • $STUP_NETWORK - Current network.
  • $STUP_USER - User who invoked stup command.
  • $STUP_TIME - Date/time of stup command invocation.
  • $STUP_ENV - Environment variables provided on stup command invocation. You can pass $STUP_ENV to another stup or docker commands in your Stupfile.

Running stup from Stupfile

Stupfile doesn't let you import another Stupfile. Instead, it lets you run stup sub-process from inside your Stupfile. This is how you can structure larger projects:

./Stupfile
./database/Stupfile
./services/scheduler/Stupfile

Top-level Stupfile calls stup with Stupfiles from sub-projects:

 restart-scheduler:
    desc: Restart scheduler
    local: >
            stup -f ./services/scheduler/Stupfile $STUP_ENV $STUP_NETWORK restart
 db-up:
    desc: Migrate database
    local: >
            stup -f ./database/Stupfile $STUP_ENV $STUP_NETWORK up

Common SSH Problem

if for some reason stup doesn't connect and you get the following error,

connecting to clients failed: connecting to remote host failed: Connect("myserver@xxx.xxx.xxx.xxx"): ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain

it means that your ssh-agent dosen't have access to your public and private keys. in order to fix this issue, follow the below instructions:

  • run the following command and make sure you have a key register with ssh-agent
ssh-add -l

if you see something like The agent has no identities. it means that you need to manually add your key to ssh-agent. in order to do that, run the following command

ssh-add ~/.ssh/id_rsa

you should now be able to use stup with your ssh key.

TODO

  • add secret vault database
  • add host manage plugin
  • add service manage plugin
  • add package manage plugin

Development

fork it, hack it..

$ make build

create new Pull Request

License

Licensed under the MIT License.