README ¶
shops - Shell Operations
shops
is a simple command-line tool written in Go
that runs a sequence of items (shell snippets) as "checks" and based on
exit status of those checks runs "actions" to correct fails items.
shops
also lets you copy files and directories to target(s) and define
shell functions for improved readability and reuse of common logic all in
regular shell.
shops
is your configuration management tool of choice when Chef, Puppet, Ansible are all too complicated and all you really want to do is run a bunch of regular shell against a set of hosts.
Table of Contents
Created by gh-md-toc
Getting Started
Install from Releases
You can install shops
by simply downloading the latest version from the
Release page for your platform
and placing the binary in your $PATH
.
For convenience you can run one of the following shell pipelines which will download and
install the latest release binary into /usr/local/bin
(modify to suit):
For Linux x86_64:
curl -s https://api.github.com/repos/prologic/shops/releases/latest | grep browser_download_url | grep Linux_x86_64 | cut -d '"' -f 4 | wget -q -O - -i - | tar -xv shops && mv shops /usr/local/bin/shops
For macOS x86_64:
curl -s https://api.github.com/repos/prologic/shops/releases/latest | grep browser_download_url | grep Darwin_x86_64 | cut -d '"' -f 4 | wget -q -O - -i - | tar -xv shops && mv shops /usr/local/bin/shops
Install from Homebrew
On macOS you can install shops
using Homebrew:
brew tap prologic/shops
brew install shops
Install from Source
To install shops
from source you can run go get
directly if you have a Go environment setup:
go get git.mills.io/prologic/shops
NOTE: Be sure to have
$GOBIN
(if not empty) or your$GOPATH/bin
in your$PATH
. See Compile and install packages and dependencies
Or grab the source code and build:
git clone https://git.mills.io/prologic/shops.git
cd shops
make build
And optionally run make install
to place the binary shops
in your $GOBIN
or $GOPATH/bin
(again see note above).
Usage
Using shops
is quite simple. The basic usage is as follows:
shops -f /path/to/spec.yml <target1> <target2> <targetN>
Where target
is either local://
to run the spec against localhost or hostname
or hostname:port
. See the format for targets above.
For example running the included sample.yml
specification file which can be
found in the ./testdata
directory in the source tree as well as other examples:
shops -f ./testdata/sample.yml 10.0.0.50
Will perform the following:
- Copy
README.md
to/root/README.md
on the server - Ensure
/tmp/foo
exists - Check the uptime of the server and display it.
Example:
shops -f ./testdata/sample.yml 10.0.0.50
10.0.0.50:22:
README.md -> /root/README.md ✅
Ensure /root/foo exists ✅ -> /root/foo
Ensure sshbox is running ✅ ->
Check Uptime ✅ -> 13:58:27 up 3 days, 1:38, 0 users, load average: 0.00, 0.00, 0.00
Targets
Targets are specified in the form:
<type>://[[<user>@]<hostname>[:<port>]]
For local targets, only the type is required, e.g: local://
.
For remote targets, the user and port are optional and if not specified in the
target they default to the -u/--user
(default: root
) and -p/--port
(default: 22
)
flags respectively.
Examples
Please peruse the Examples where I (and hopefully others) will place real-life examples of various types of tasks over time. Mostly these are biased towards my home infrastructure (a little server room with a 22RU rack cabinet and server gear). If you end up using shops
in your infrastructure, even if it's just a Raspberry Pi, feel free to submit PR(s) to add useful examples and use-cases here too! 🙇
Authentication
Remote targets are operated on via the SSH protocol using the ssh://
type
which is implied by default or if the target looks like it might be a hostname
or host:port
pair.
Right now the only supported authentication methods are:
- SSH Agent
This means you must have a locally running ssh-agent
and it must
have the identities you intend to use to operate on.
You can list these with ssh-add -l
. If you do not have any listed this is
likely the most common cause of "authentication failure" errors.
There is an issue (#9) in the backlog to address adding support for other authentication mechanisms such as:
- Password based authentication with secure prompts
- Key based authentication by providing an identity file and securely prompting for passphrase if applicable.
Specification File Format
The specification file format is a simple YAML file with the following structure:
---
veresion: 1
env:
FOO: bar
BAR: ${FOO}
files:
- source: foo
target: /tmp/foo
funcs:
foo: |
echo "I am a function!"
items:
- name: Check #1
check: true
actino: foo
- name: Checek #2
check: false
action: echo ${BAR}
A valid spec consists of a number of top-level keys:
version
-- Which for the moment is ignored, but might be used to version the specification file for future enhancements in a backwards compatible way.env
-- Environment variables defined as a map of keys and values (order is preserved) and shell interpolation is supported. Shell interpolation occurs on the target(s), not locally. Variables can be overridden with the-e/--env
flag with the formKEY[=<value>]
. If value is omitted the value is taken from the local environment whereshops
is run.files
-- Declares one or more files or directories to be copied to each target. Directories are copied recursively. Currently no checks are performed, but this is planned (#4).funcs
-- A mapping of function name to the function's body. There is no need to write the function name withfoo() { ... }
as theshops
runner(s) will do this automatically when injecting functions into the session(s) (in fact doing so in an error).items
-- One or more items of configuration to be applied to each target. Each item declares a "check" and "action". Checks and actions are written in regular shell. If a check fails, the action is run to correct the failed state. If all checks pass, no actions are run. If an action fails the target is considered failed unless-c/--continue-on-error
flag is passed toshops
.
Validation
shops
by default-runs the "check" of each item to validate the "action".
If an action is intended to be run regardless of the state of the check, then
the skip_validation
key can be set to true
to skip validation.
Example:
---
version: 1
items:
- name: Skip validation
check: false
action: echo "Hello World"
This behavior ensures that not only are failed checks fixed by appropriate actions, but that those actions are validated to be correct against the check asserting the state in the first place.
License
shops
is licensed under the terms of the MIT License
Documentation ¶
There is no documentation for this package.