From 7f20043bbb5d1e07e42ff277ac0e679aa4027322 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 10 Jun 2013 22:15:06 -0700 Subject: [PATCH] website: start docs on custom builders --- .../source/docs/extend/builder.html.markdown | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 website/source/docs/extend/builder.html.markdown diff --git a/website/source/docs/extend/builder.html.markdown b/website/source/docs/extend/builder.html.markdown new file mode 100644 index 000000000..c4890067c --- /dev/null +++ b/website/source/docs/extend/builder.html.markdown @@ -0,0 +1,119 @@ +--- +layout: "docs" +--- + +# Custom Builder Development + +Builders are the components of Packer responsible for creating a machine, +bringing it to a point where it can be provisioned, and then turning +that provisioned machine into some sort of machine image. Several builders +are officially distributed with Packer itself, such as the AMI builder, the +VMware builder, etc. However, it is possible to write custom builders using +the Packer plugin interface, and this page documents how to do that. + +Prior to reading this page, it is assumed you have read the page on +[plugin development basics](/docs/extend/developing-plugins.html). + +
+ Warning! This is an advanced topic. If you're new to Packer, + we recommend getting a bit more comfortable before you dive into writing + plugins. +
+ +## The Interface + +The interface that must be implemented for a builder is the `packer.Builder` +interface. It is reproduced below for easy reference. The reference below +also contains some basic documentatin of what each of the methods are +supposed to do. + +
+type Builder interface {
+	// Prepare is responsible for reading in some configuration, in the raw form
+	// of map[string]interface{}, and storing that state for use later. Any setup
+	// should be done in this method. Note that NO side effects should really take
+	// place in prepare. It is meant as a state setup step only.
+	Prepare(config interface{}) error
+
+	// Run is where the actual build should take place. It takes a Ui to
+	// send messages to the user, Hook to execute hooks, and Cache in order
+	// to save files across runs.
+	Run(Ui, Hook, Cache) Artifact
+
+	// Cancel cancels a possibly running Builder. This should block until
+	// the builder actually cancels and cleans up after itself.
+	Cancel()
+}
+
+ +### The "Prepare" Method + +The `Prepare` method for each builder is called prior to any runs with +the configuration that was given in the template. This is passed in as +an `interface{}` type, but is generally `map[string]interface{}`. The prepare +method is responsible for translating this configuration into an internal +structure, validating it, and returning any errors. + +For decoding the `interface{}` into a meaningful structure, the +[mapstructure](https://github.com/mitchellh/mapstructure) library is recommended. +Mapstructure will take an `interface{}` and decode it into an arbitrarily +complex struct. If there are any errors, it generates very human friendly +errors that can be returned directly from the prepare method. + +While it is not actively enforced, **no side effects** should occur from +running the `Prepare` method. Specifically, don't create files, don't launch +virtual machines, etc. Prepare's purpose is solely to configure the builder +and validate the configuration. + +### The "Run" Method + +`Run` is where all the interesting stuff happens. Run is executed, often +in parallel for multiple builders, to actually build the machine, provision +it, and create the resulting machine image, which is returned as an +implementation of the `packer.Artifact` interface. + +The `Run` method takes three parameters. These are all very useful. The +`packer.Ui` object is used to send output to the console. `packer.Hook` is +used to execute hooks, which are covered in more detail in the hook section +below. And `packer.Cache` is used to store files between multiple Packer +runs, and is covered in more detail in the cache section below. + +Because builder runs are typically a complex set of many steps, the +[multistep](https://github.com/mitchellh/multistep) library is recommended +to bring order to the complexity. Multistep is a library which allows you to +separate your logic into multiple distinct "steps" and string them together. +It fully supports cancellation mid-step and so on. Please check it out, it is +how the built-in builders are all implemented. + +Finally, as a result of `Run`, an implementation of `packer.Artifact` should +be returned. More details on creating a `packer.Artifact` are covered in the +artifact section below. + +### The "Cancel" Method + +The `Run` method is often run in parallel. The `Cancel` method can be +called at any time and requests cancellation of any builder run in progress. +This method should block until the run actually stops. + +Cancels are most commonly triggered by external interrupts, such as the +user pressing `Ctrl-C`. Packer will only exit once all the builders clean up, +so it is important that you architect your builder in a way that it is quick +to respond to these cancellations and clean up after itself. + +## Creating an Artifact + +TODO + +## Hooks + +TODO + +## Provisioning + +TODO + +## Caching Files + +TODO + +