Skip to content

Commit

Permalink
Add API section to README; add HACKING.md; remove Makefile (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
benhoyt committed Sep 15, 2021
1 parent 4c5d8c1 commit 78ab29b
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 66 deletions.
130 changes: 130 additions & 0 deletions HACKING.md
@@ -0,0 +1,130 @@
# Hacking on Pebble

Hacking on Pebble is easy. It's written in Go, so install or [download](https://golang.org/dl/) a copy of the latest version of Go. Pebble uses [Go modules](https://golang.org/ref/mod) for managing dependencies, so all of the standard Go tooling just works.

To compile and run Pebble, use the `go run` command on the `cmd/pebble` directory. The first time you run it, it will download dependencies and build packages, so will take a few seconds (but after that be very fast):

```
$ go run ./cmd/pebble
Pebble lets you control services and perform management actions on
the system that is running them.
Usage: pebble <command> [<options>...]
...
```

If you want to build and install the executable to your `~/go/bin` directory (which you may want to add to your path), use `go install`:

```
$ go install ./cmd/pebble
```

However, during development it's easiest just to use `go run`, as that will automatically recompile if you've made any changes.


## Running the daemon

To run the Pebble daemon, set the `$PEBBLE` environment variable and use the `pebble run` sub-command, something like this:

```
$ mkdir ~/pebble
$ export PEBBLE=~/pebble
$ go run ./cmd/pebble run
2021-09-15T01:37:23.962Z [pebble] Started daemon.
...
```


## Using the CLI client

The use the Pebble command line client, run one of the other Pebble sub-commands, such as `pebble plan` or `pebble services` (if the server is running in one terminal, do this in another):

```
$ export PEBBLE=~/pebble
$ go run ./cmd/pebble plan
services:
snappass:
override: replace
command: sleep 60
$ go run ./cmd/pebble services
Service Startup Current
snappass disabled inactive
```


## Using Curl to hit the API

For debugging, you can also use [curl](https://curl.se/) in Unix socket mode to hit the Pebble API:

```
$ curl --unix-socket ~/pebble/.pebble.socket 'http://localhost/v1/services?names=snappass' | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 120 100 120 0 0 117k 0 --:--:-- --:--:-- --:--:-- 117k
{
"type": "sync",
"status-code": 200,
"status": "OK",
"result": [
{
"name": "snappass",
"startup": "disabled",
"current": "inactive"
}
]
}
```


## Running the tests

Pebble has a suite of Go unit tests, which you can run using the regular `go test` command. To test all packages in the Pebble repository:

```
$ go test ./...
ok github.com/canonical/pebble/client (cached)
? github.com/canonical/pebble/cmd [no test files]
ok github.com/canonical/pebble/cmd/pebble 0.095s
...
```

To test a single package, simply pass the package path to `go test`:

```
$ go test ./cmd/pebble
ok github.com/canonical/pebble/cmd/pebble 0.115s
```

To run a single suite or a single test, pass the suite or test name to the [gocheck](https://labix.org/gocheck) test runner:

```
$ go test ./cmd/pebble -v -check.v -check.f PebbleSuite
=== RUN Test
PASS: cmd_add_test.go:38: PebbleSuite.TestAdd 0.002s
PASS: format_test.go:52: PebbleSuite.TestCanUnicode 0.000s
...
PASS: cmd_version_test.go:26: PebbleSuite.TestVersionCommand 0.000s
OK: 20 passed
--- PASS: Test (0.02s)
PASS
ok github.com/canonical/pebble/cmd/pebble 0.022s
$ go test ./cmd/pebble -v -check.v -check.f PebbleSuite.TestAdd
=== RUN Test
PASS: cmd_add_test.go:38: PebbleSuite.TestAdd 0.002s
OK: 1 passed
--- PASS: Test (0.00s)
PASS
ok github.com/canonical/pebble/cmd/pebble 0.007s
```

Note that during CI we run the tests with `-race` to catch data races:

```
$ go test -race ./...
ok github.com/canonical/pebble/client (cached)
? github.com/canonical/pebble/cmd [no test files]
ok github.com/canonical/pebble/cmd/pebble 0.165s
...
```
59 changes: 0 additions & 59 deletions Makefile

This file was deleted.

52 changes: 45 additions & 7 deletions README.md
@@ -1,4 +1,6 @@
## Take control of your internal daemons!
# The Pebble service manager

_Take control of your internal daemons!_

**Pebble** helps you to orchestrate a set of local service processes as an organized set.
It resembles well known tools such as _supervisord_, _runit_, or _s6_, in that it can
Expand All @@ -9,7 +11,10 @@ designed with unique features that help with more specific use cases.
- [Layer configuration examples](#layer-configuration-examples)
- [Running pebble](#running-pebble)
- [Layer specification](#layer-specification)
- [TODO/Contributing](#todo-contributing)
- [API and clients](#api-and-clients)
- [Roadmap/TODO](#roadmap--todo)
- [Hacking / Development](#hacking--development)
- [Contributing](#contributing)

## General model

Expand Down Expand Up @@ -115,7 +120,7 @@ services:

## Running pebble

Once the `$PEBBLE` directory is setup, running it is easy:
If pebble is installed and the `$PEBBLE` directory is set up, running it is easy:

$ pebble run

Expand Down Expand Up @@ -209,10 +214,31 @@ services:
group-id: <gid>
```

## TODO/Contributing
## API and clients

The Pebble daemon exposes an API (HTTP over a Unix socket) to allow remote clients to interact with the daemon. It can start and stop services, add configuration layers the plan, and so on. There is currently no official documentation for the API (apart from the [code itself](https://github.com/canonical/pebble/blob/master/internal/daemon/api.go)!); most users will interact with it via the Pebble command line interface or the Go or Python client.

The [Go client](https://pkg.go.dev/github.com/canonical/pebble/client) is used by the CLI to connect to the Pebble API. You can use this as follows:

```go
pebble, err := client.New(&client.Config{Socket: ".pebble.socket"})
if err != nil {
return err
}
files, err := pebble.Start(&client.ServiceOptions{Names: []string{"srv1"}})
if err != nil {
return err
}
```

We try to never change the underlying API itself in a backwards-incompatible way, however, we may sometimes change the Go client in backwards-incompatible ways.

In addition to the Go client, there's also a [Python client](https://github.com/canonical/operator/blob/master/ops/pebble.py) for the Pebble API that's part of the Python Operator Framework used by Juju charms ([documentation here](https://juju.is/docs/sdk/pebble)).

## Roadmap / TODO

This is a preview of what Pebble is becoming. Please keep that in mind while you
explore around.
explore.

Here are some of the things coming soon:

Expand All @@ -224,11 +250,23 @@ Here are some of the things coming soon:
- [x] General system modification commands (writing configuration files, etc)
- [x] Better log caching and retrieval support
- [x] Consider showing unified log as output of `pebble run` (use `-v`)
- [ ] Add support for automatically removing (double) timestamps from logs
- [ ] Automatically restart services that fail
- [ ] Support for custom health checks (HTTP, TCP, command)
- [ ] Automatically remove (double) timestamps from logs
- [ ] Improve signal handling, e.g., sending SIGHUP to a service
- [ ] Terminate all services before exiting run command
- [ ] More tests for existing CLI commands

## Hacking / Development

See [HACKING.md](HACKING.md) for information on how to run and hack on the Pebble codebase during development. In short, use `go run ./cmd/pebble`.

## Contributing

We welcome quality external contributions. We have good unit tests for much of the code, and a thorough code review process. Please note that unless it's a trivial fix, it's generally worth opening an issue to discuss before submitting a pull request.

Before you contribute a pull request you should sign the [Canonical contributor agreement](https://ubuntu.com/legal/contributors) -- it's the easiest way for you to give us permission to use your contributions.

## Have fun!

... and enjoy the rest of 2021!
... and enjoy the rest of the year!

0 comments on commit 78ab29b

Please sign in to comment.