Skip to content

Commit fd20628

Browse files
committed
add basic documentation
1 parent 2043675 commit fd20628

File tree

3 files changed

+124
-9
lines changed

3 files changed

+124
-9
lines changed

README.md

Lines changed: 122 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,126 @@
11
# Wadsworth
22

3-
_The Mister Handy robot of automation!_
3+
_The [Mister Handy robot][wadsworth] of automation!_
44

5-
![https://d1u5p3l4wpay3k.cloudfront.net/fallout_gamepedia/8/8c/Mister_Handy.png?version=e4b210e0cf711aefe37d6c3fccb8bc8e](https://d1u5p3l4wpay3k.cloudfront.net/fallout_gamepedia/8/8c/Mister_Handy.png?version=e4b210e0cf711aefe37d6c3fccb8bc8e)
5+
Wadsworth is a git-driven task runner to automate the application of configs.
66

7-
(Work in progress, come back later...)
7+
## Overview
8+
9+
Wadsworth is a little tool for implementing [Git-Ops][git-ops] in single-server environments. It's not a cloud/cluster
10+
tool however it could easily be used as one, but you'd probably be better off using something like
11+
[kube-applier][kube-applier], [Terraform][terraform], [Ansible][ansible] or any of these more "serious" tools.
12+
13+
Instead, Wadsworth aims to be extremely simple. You give it some Git repositories and tell it to run commands when those
14+
Git repositories receive commits and that's about it. It also provides a way of safely passing in credentials from
15+
[Hashicorp's Vault][vault] so you can say goodbye to storing your MySQL password in a .env file!
16+
17+
## Usage
18+
19+
Currently, Wadsworth has a single command: `run` and it takes a single parameter: a Git URL. This Git URL defines the
20+
"Config Repo" which contains Wadsworth configuration files. These configuration files declare where Wadsworth can find
21+
"Target Repos" which are the repos that contain all the stuff you want to automate. The reason Wadsworth is designed
22+
this way instead of just using the target repos to define what Wadsworth should do is 1. to consolidate Wadsworth config
23+
into one place, 2. separate the config of the tools from the applications and 3. keep your target repos clean.
24+
25+
### Configuration
26+
27+
The precursor to Wadsworth used JSON for configuration, this was fine for simple tasks but the ability to provide a
28+
little bit of logic and variables for repetitive configurations is very helpful. Inspired by [StackExchange's
29+
dnscontrol][dnscontrol], Wadsworth uses JavaScript files as configuration. This provides a JSON-like environment with
30+
the added benefit of conditional logic.
31+
32+
Here's a simple example of a configuration that should exist in the Wadsworth config repo that re-deploys a Docker
33+
Compose stack whenever it changes:
34+
35+
```js
36+
T({
37+
name: "my_app",
38+
url: "git@github.com:username/my-docker-compose-project",
39+
up: ["docker-compose", "up", "-d"],
40+
down: ["docker-compose", "down"]
41+
});
42+
```
43+
44+
#### The `T` Function
45+
46+
The `T` function declares a "Target" which is essentially a Git repository. In this example, the repository
47+
`git@github.com:username/my-docker-compose-project` would contain a `docker-compose.yml` file for some application
48+
stack. Every time you make a change to this file and push it, Wadsworth will pull the new version and run the command
49+
defined in the `up` attribute of the target, which is `docker-compose up -d`.
50+
51+
You can put as many target declarations as you want in the config file, and as many config files as you want in the
52+
config repo. You can also use variables to cut down on repeated things:
53+
54+
```js
55+
var GIT_HOST = "git@github.com:username/";
56+
T({
57+
name: "my_app",
58+
url: GIT_HOST + "my-docker-compose-project",
59+
up: ["docker-compose", "up", "-d"]
60+
});
61+
```
62+
63+
Or, if you have a ton of Docker Compose projects and they all live on the same Git host, why not declare a function that
64+
does all the hard work:
65+
66+
```js
67+
var GIT_HOST = "git@github.com:username/";
68+
69+
function Compose(name) {
70+
return {
71+
name: name,
72+
url: GIT_HOST + name,
73+
up: ["docker-compose", "up", "-d"]
74+
};
75+
}
76+
77+
T(Compose("homepage"));
78+
T(Compose("todo-app"));
79+
T(Compose("world-domination-scheme"));
80+
```
81+
82+
The object passed to the `T` function accepts the following keys:
83+
84+
- `name`: The name of the target
85+
- `url`: The Git URL (ssh or https)
86+
- `up`: The command to run on first-run and on changes
87+
- `down`: The command to run when the target is removed
88+
- `env`: Environment variables to pass to the target
89+
90+
#### The `E` Function
91+
92+
The only other function available in the configuration runtime is `E`, this declares an environment variable that will
93+
be passed to the `up` and `down` commands for all targets.
94+
95+
For example:
96+
97+
```js
98+
E("MOUNT_POINT", "/data");
99+
T({ name: "postgres", url: "...", up: "docker-compose", "up", "-d" });
100+
```
101+
102+
This would pass the environment variable `MOUNT_POINT=/data` to the `docker-compose` invocation. This is useful if you
103+
have a bunch of compose configs that all mount data to some path on the machine, you then use
104+
`${MOUNT_POINT}/postgres:/var/lib/postgres/data` as a volume declaration in your `docker-compose.yml`.
105+
106+
## Roadmap
107+
108+
The current implementation is an MVP that does one thing well, but there some features I'd like to implement in future
109+
to ease the maintenance and user experience:
110+
111+
- Daemon control - currently, `wadsworth run` will just run and block until it is killed, I would like to provide a way
112+
to interact with a running instance of `wadsworth` via a Unix socket file and a simple API (similar to Docker). This
113+
would open up the ability to perform forced triggers of targets or disable certain targets via the command line.
114+
- Proper releases - Right now you grab the binary and run it, how you daemonise it is up to you. I'd like to provide a
115+
systemd unit file and a Snapcraft app for easier installation and usage.
116+
- Dependency Tree - this is a maybe but it could be useful if all repos are both config repos and target repos. In other
117+
words, every repo can contain `.js` config files to build a dependency tree of repos. But I'm not sure if there's a
118+
use-case for this yet (or ever).
119+
120+
[wadsworth]: https://d1u5p3l4wpay3k.cloudfront.net/fallout_gamepedia/8/8c/Mister_Handy.png
121+
[git-ops]: https://www.weave.works/blog/gitops-operations-by-pull-request
122+
[kube-applier]: https://github.com/box/kube-applier
123+
[terraform]: https://terraform.io
124+
[ansible]: https://ansible.com
125+
[vault]: https://vaultproject.io
126+
[dnscontrol]: https://stackexchange.github.io/dnscontrol/

main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ func main() {
4545

4646
app.Name = "wadsworth"
4747
app.Usage = "A git-driven task automation butler."
48-
app.UsageText = `TODO: Short usage info`
48+
app.UsageText = `wadsworth [flags] [command]`
4949
app.Version = version
50-
app.Description = `TODO: Longform description`
50+
app.Description = `Wadsworth is a git-driven task runner to automate the application of configs.`
5151
app.Author = "Southclaws"
5252
app.Email = "hello@southcla.ws"
5353

makefile

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ LDFLAGS := -ldflags "-X main.version=$(VERSION)"
88
# Local Development
99
#-
1010

11-
static:
12-
go get
13-
CGO_ENABLED=0 GOOS=linux go build -a $(LDFLAGS) -o $(SERVICE) .
14-
1511
fast:
1612
go build $(LDFLAGS) -o $(SERVICE)
1713

0 commit comments

Comments
 (0)