Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add Developing Tsuru Plugins (branch: beta-v2) #216

Open
wants to merge 3 commits into
base: beta-v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ fmt: ## Format your code with gofmt
$(GOFMT) -w .

yamlfmt: ## Format your code with yamlfmt
ifeq (, $(shell which yamlfmt))
ifeq (, $(shell which yamlfmt 2>/dev/null ))
go install github.com/google/yamlfmt/cmd/[email protected]
endif
yamlfmt .

addlicense: ## Add licence header to all files
ifeq (, $(shell which addlicense))
ifeq (, $(shell which addlicense 2>/dev/null ))
go install github.com/google/addlicense@latest
endif
addlicense -f LICENSE-HEADER .
Expand Down Expand Up @@ -89,21 +89,21 @@ ifneq (, $(shell $(GOFMT) -l . ))
@echo "Please run '$(CYAN)make fmt$(RESET)' to format your code"
@exit 1
endif
ifeq (, $(shell which staticcheck))
ifeq (, $(shell which staticcheck 2>/dev/null ))
go install honnef.co/go/tools/cmd/staticcheck@latest
endif
staticcheck ./...

lint-yaml: ## Check the yaml is valid and correctly formatted
ifeq (, $(shell which yamlfmt))
ifeq (, $(shell which yamlfmt 2>/dev/null ))
go install github.com/google/yamlfmt/cmd/[email protected]
endif
@echo "yamlfmt --quiet --lint ."
@yamlfmt --quiet --lint . \
|| ( echo "Please run '$(CYAN)make yamlfmt$(RESET)' to fix it (if a format error)" && exit 1 )

lint-license-header: ## Check if all files have the license header
ifeq (, $(shell which addlicense))
ifeq (, $(shell which addlicense 2>/dev/null ))
go install github.com/google/addlicense@latest
endif
@echo "addlicense -check -f LICENSE-HEADER -ignore coverage/** ."
Expand Down Expand Up @@ -140,7 +140,7 @@ env: ## Print useful environment variables to stdout
@echo '$$(FILES#) :' $(shell echo $(FILES) | wc -w)

setup: ## Setup some dev dependencies (eg: pre-commit)
ifeq (, $(shell which pre-commit))
ifeq (, $(shell which pre-commit 2>/dev/null ))
@echo "pre-commit is not installed. Check $(CYAN)https://pre-commit.com/#install$(RESET)"
endif
pre-commit install --install-hooks
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,14 @@

tsuru is a command line for application developers on
[tsuru](https://github.com/tsuru/tsuru).

## Tsuru plugins

Tsuru plugins are the standard way to extend tsuru-client functionality transparently.
Installing and using a plugin is done with:
```
tsuru plugin install <plugin-name> <plugin-url>
tsuru <plugin-name> <any_sub_commands_or_flags...>
```

For developing a custom plugin, read about [Developing Tsuru Plugins](./pkg/cmd/plugin.md).
4 changes: 3 additions & 1 deletion internal/exec/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ func TestOsExec(t *testing.T) {

func init() {
if runtime.GOOS == "windows" {
endLine = "\r\n"
// windows ends echo with \n or \r\n ?!?
endLine = "\n"
// endLine = "\r\n"
}
}
80 changes: 80 additions & 0 deletions pkg/cmd/plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Developing Tsuru Plugins

Tsuru plugins are the standard way to extend tsuru-client functionality transparently.

A tsuru-client plugin is any runnable file, located inside `~/.tsuru/plugins` directory.
It works by finding the runnable file (with or without extension) with that plugin name.

A simple working example:
```bash
cat > ~/.tsuru/plugins/myplugin.sh <<"EOF"
#!/bin/sh
echo "Hello from tsuru plugin ${TSURU_PLUGIN_NAME}!"
echo " called with args: $@"
EOF

chmod +x ~/.tsuru/plugins/myplugin.sh

tsuru myplugin subcommands -flags

##### printed:
# Hello from tsuru plugin myplugin!
# called with args: subcommands -flags
```

You may find available tsuru plugins on github, by searching for the topic [`tsuru-plugin`](https://github.com/topics/tsuru-plugin).
(If you are developing a plugin, please tag your github repo).

## Distributing a tsuru plugin

The best way to distribute a tsuru plugin is making it compatible with `tsuru plugin install`.
There are different approaches for distributing the plugin,
depending on the language used for building it.

### script-like single file
If the plugin is bundled as a **script-like single file** (eg: shell script, python, ruby, etc...)
you may make it available for download on a public URL.
The name of the file is irrelevant on this case.

### bundle of multiple files
If the plugin is bundled as **multiple files**, you should compact them inside a `.tar.gz` or `.zip` file,
and make it available for download on a public URL.
In this case, the file entrypoint must has the same name as the plugin (file extension is optional).
The CLI will call the binary at `~/.tsuru/plugins/myplugin/myplugin[.ext]`.

### compiled binary
If the plugin is bundled as a **compiled binary**, you should create a `manifest.json` file
(as defined on issue [#172](https://github.com/tsuru/tsuru-client/issues/172))
which tells where to download the appropriate binary:
```json
{
"SchemaVersion": "1.0",
"Metadata": {
"Name": "<pluginName>",
"Version": "<pluginVersion>"
},
"UrlPerPlatform": {
"<os>/<arch>": "<os_arch_url>",
...
}
}
```

Each supported os/arch (check the latest release), should be compacted as `.tar.gz` or `.zip` file.
All files (`manifest.json` and all compacted binaries) must available for download on public URLs.

An example of such a plugin, hosted on github, is the
[`rpaasv2` plugin](https://github.com/tsuru/rpaas-operator/issues/124),
installed using this [manifest.json](https://github.com/tsuru/rpaas-operator/releases/latest/download/manifest.json).

## Available ENV variables

When a plugin is called, the main tsuru-client passes some additional environment variables:

| env | description |
| ----------------- | ------------------------------------------------------ |
| TSURU_TARGET | tsuru server url (eg: https://tsuru.io) |
| TSURU_TOKEN | tsuru authentication token |
| TSURU_VERBOSITY | 0: default, 1: log requests, 2: log responses |
| TSURU_FORMAT | output format (json, table, etc...) as in [printer.OutputFormat](../printer/printer.go) |
| TSURU_PLUGIN_NAME | name called from the main tsuru-client |
Loading