Skip to content

Commit

Permalink
Add advanced plan writing guide
Browse files Browse the repository at this point in the history
Signed-off-by: Tasha Drew <[email protected]>
  • Loading branch information
tashimi committed Sep 29, 2017
1 parent 850d80f commit 9062089
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 2 deletions.
2 changes: 2 additions & 0 deletions www/data/docs_sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ sidebar_links:
link: "#ecs-and-habitat"
- title: "Apache Mesos and DC/OS"
link: "#mesos-dcos"
- title: "Advanced Plan.sh Writing"
link: "#planwriting-guide"
- title: Iterative Development
link: "#iterative-development"
- title: "Binary Wrapper Packages"
Expand Down
2 changes: 2 additions & 0 deletions www/source/docs/best-practices.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ We focus on best practices for packages that use Builder for continuous builds
<%= partial "/partials/docs/bp-ecs-and-habitat"%>

<%= partial "/partials/docs/bp-mesos-dcos"%>

<%= partial "/partials/docs/bp-planwriting-guide"%>
---
<%= partial "/partials/docs/bp-iterative-development"%>
---
Expand Down
4 changes: 2 additions & 2 deletions www/source/docs/index.html.slim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Habitat documentation
title: Habitat Documentation
description: All of the encyclopedic knowledge of the habitat project.
---
section.docs--hero
Expand Down Expand Up @@ -115,7 +115,7 @@ section.docs--quicklink
| Guide
.body-content
h4
a href="https://habitat.sh/guides/writing-plans"
a href="https://www.habitat.sh/docs/best-practices/#planwriting-guide"
| Developer Guide
p
| Instructions for setting up your environment to develop Habitat. Building, testing, and contributing code.
121 changes: 121 additions & 0 deletions www/source/partials/docs/_bp-planwriting-guide.html.md.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# <a name="planwriting-guide" id="planwriting-guide" data-magellan-target="planwriting-guide">Advanced Plan Writing Guide</a>

# Requirements to add a plan to core plans

The following is a best practice guide to how to write a production quality plan.sh. These best practices are reflected in the requirements for a user to contribute a plan to the Habitat [Core Plans](https://github.com/habitat-sh/core-plans/).

If you haven't already, a good first step is to read [the Developing Packages articles.](/docs/developing-packages/)

A well written plan.sh consists of well-formed:

- [Package Metadata](#package-metadata)
- [Package Name Conventions](#package-name-conventions)
- [Plan syntax](#plan-syntax)

## Package Metadata

Each package plan should contain a value adhering to the guidelines for each of the following elements:

- `pkg_description`
- `pkg_license` (in [SPDX format](http://spdx.org/licenses/))
- `pkg_maintainer` in the format of "The Habitat Maintainers <humans@habitat.sh>"
- `pkg_name` see the section of this document on "Package Name Conventions"
- `pkg_origin` must be set to `core`
- `pkg_source`
- `pkg_upstream_url`
- `pkg_version` must be the complete version number of the software

## Package Name Conventions

Each package is identified by a unique string containing four sub-strings separated
by a forward slash (`/`) called a [PackageIdent](/docs/glossary/#glossary-packages).

`origin`/`name`/`version`/`release`

The `origin`, `name`, and `version` values of this identifier are user defined by
setting their corresponding variable in your `plan.sh` file while the value of
`release` is generated at build-time.

The value of `name` should exactly match the name of the project it represents and the `plan.sh` file should be located within a directory of the same name in this repository.

> Example: The plan for the [bison project](https://www.gnu.org/software/bison/) project contains setting `pkg_name=bison` and resides in `$root/bison/plan.sh`.

There is one exception to this rule: Additional plans may be defined for projects for their past major versions by appending the major version number to its name. The `plan.sh` file for this new package should be located within a directory of the same name.

> Example: the [bison project](https://www.gnu.org/software/bison/) maintains the 2.x line along with their current major version (at time of writing: 3.x). A second plan is created as `bison2` and placed within a directory of the same name in this repository.

Packages meeting this exception will always have their latest major version found in the package sharing the exact name of their project. A new package will be created for the previous major version following these conventions.

> Example: the [bison project](https://www.gnu.org/software/bison/) releases the 4.x line and is continuing to support Bison 3.x. The `bison` package is copied to `bison3` and the `bison` package is updated to build Bison 4.x.

## Adding an older version of a core package

Sometimes you may need a version of software that we are packaging which was released before the project's corresponding Habitat core package was created.

Please *do not* issue a PR containing a new plan for the specific version of software that you need unless the software project it packages meets the exceptional cases outlined in the above section "Package Name Conventions". Instead [create an issue](https://github.com/habitat-sh/core-plans/issues/new) containing the name and version of the software that you want published to [Habitat Builder](https://bldr.habitat.sh). A maintainer will run a one-off build and publish the generated artifact to the public depot and close your issue once the work is completed.

Issues with an associated gist containing a working fork of our current plan which builds the version of the software will be attended to first.

## Plan syntax

You can review the entire [plan syntax guide here](https://www.habitat.sh/docs/developing-packages/).

Please note that the following conditions must be observed for any plan to be merged into core plans (and are important best practices for any plan):

### Plan basic settings

You can read more about [basic plan settings](https://www.habitat.sh/docs/developing-packages/#write-plans) here. The minimum requirements for a core plan are:

- pkg_name is set
- pkg_origin is set
- pkg_shasum is set
- pkg_description is set

### Callbacks

You can read more about [callbacks](https://www.habitat.sh/docs/reference/#reference-callbacks) here. The minimum requirement for a core plan are:

#### Do's

- `do_prepare()` is a good place to set environment variables and set the table to build the software. Think of it as a good place to do patches.

#### Don't's

- You should never call `exit` within a build phase. You should instead return an exit code such as `return 1` for failure, and `return 0` for success.
- If you clone a repo from git, you must override `do_verify()` to `return 0`.
- Never use `pkg_source` unless you are downloading something as a third party.
- You should never shell out to `hab` from within a callback. If you think you want to, you should use a [utility function](https://www.habitat.sh/docs/reference/#utility-functions) instead.
- You should not call any function or helper that begin with an underscore, for example `_dont_call_this_function()`. Those are internal only functions that are not supported for external use and will break your plan if you call them.
- Don't run any code or run anything outside of a build phase or bash function.

### Hooks

The supervisor dynamically invokes hooks at run-time, triggered by an application lifecycle event. You can read more about [hooks](https://www.habitat.sh/docs/reference/#reference-hooks) here.

- You cannot block the thread in a hook unless it is in the `run` hook. Never call `hab` or `sleep` in a hook that is not the `run` hook.
- You should never shell out to `hab` from within a hook. If you think you want to, you should use a [runtime configuration setting](https://www.habitat.sh/docs/reference/#template-data) instead. If none of those will solve your problem, open an issue and tell the core team why.
- Run hooks should:
- Redirect `stderr` to `stdout` (e.g. with `exec 2>&1` at the start of the hook)
- Call the command to execute with `exec <command> <options>` rather than running the command directly. This ensures the command is executed in the same process and that the service will restart correctly on configuration changes.
- If you are running something with a pipe `exec` won't work.
- Attempting to execute commands as a `root` user or trying to do `sudo hab install` are not good practice.
- Don't edit any of the Supervisor rendered templates.
- You can only write to: `/var/`, `/static/`, `/data/` directories. You should only access these with your `runtime configuration setting` variable.
- No one should ever edit anything in `/hab/` directly.
- No one should write to anything in `/hab/` directly.

### README

All plans should have a README. In core plans, it is a hard requirement. Your README at a bare minimum should include:

- Your name as maintainer and supporter of this plan.
- Absolutely required:
- What habitat topology it uses (and the plan should have the correct topology for the technology).
- Clear, step by step instructions as to how to use the package successfully.
- What is the best update strategy for different deployments?
- What are some configuration updates a user can make, or do they always need to do a full rebuild?
- Strongly recommended:
- Documentation on how to scale the service.
- Instructions on how to monitor the health of the service at the application layer.
- Can a user simply call the package as a dependency of their application?
- How does the package integrate into their

0 comments on commit 9062089

Please sign in to comment.