Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
packer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kristopher Ruzic
packer
Commits
25afaf83
Commit
25afaf83
authored
Jun 20, 2013
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
website: custom provisioner docs
parent
192253c8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
119 additions
and
1 deletion
+119
-1
website/source/docs/extend/provisioner.html.markdown
website/source/docs/extend/provisioner.html.markdown
+118
-0
website/source/layouts/docs.erb
website/source/layouts/docs.erb
+1
-1
No files found.
website/source/docs/extend/provisioner.html.markdown
0 → 100644
View file @
25afaf83
---
layout
:
"
docs"
---
# Custom Provisioner Development
Provisioners are the components of Packer that install and configure
software into a running machine prior to turning that machine into an
image. An example of a provisioner is the
[
shell provisioner
](
/docs/provisioners/shell.html
)
,
which runs shell scripts within the machines.
Prior to reading this page, it is assumed you have read the page on
[
plugin development basics
](
/docs/extend/developing-plugins.html
)
.
Provisioner plugins implement the
`packer.Provisioner`
interface and
are served using the
`plugin.ServeProvisioner`
function.
<div
class=
"alert alert-block"
>
<strong>
Warning!
</strong>
This is an advanced topic. If you're new to Packer,
we recommend getting a bit more comfortable before you dive into writing
plugins.
</div>
## The Interface
The interface that must be implemented for a provisioner is the
`packer.Provisioner`
interface. It is reproduced below for easy reference.
The reference below also contains some basic documentation of what each of
the methods are supposed to do.
<pre
class=
"prettyprint"
>
// A provisioner is responsible for installing and configuring software
// on a machine prior to building the actual image.
type Provisioner interface {
// Prepare is called with a set of configurations to setup the
// internal state of the provisioner. The multiple configurations
// should be merged in some sane way.
Prepare(...interface{}) error
// Provision is called to actually provision the machine. A UI is
// given to communicate with the user, and a communicator is given that
// is guaranteed to be connected to some machine so that provisioning
// can be done.
Provision(Ui, Communicator)
}
</pre>
### The "Prepare" Method
The
`Prepare`
method for each provisioner is called prior to any runs with
the configuration that was given in the template. This is passed in as
an array of
`interface{}`
types, 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 multiple parameters, they should be merged together into the final
configuration, with later parameters overwriting any previous configuration.
The exact semantics of the merge are left to the builder author.
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
`Prepare`
method is called very early in the build process so that
errors may be displayed to the user before anything actually happens.
### The "Provision" Method
The
`Provision`
method is called when a machine is running and ready
to be provisioned. The provisioner should do its real work here.
The method takes two parameters: a
`packer.Ui`
and a
`packer.Communicator`
.
The UI can be used to communicate with the user what is going on. The
communicator is used to communicate with the running machine, and is
guaranteed to be connected at this point.
The provision method should not return until provisioning is complete.
## Using the Communicator
The
`packer.Communicator`
parameter and interface is used to communicate
with running machine. The machine may be local (in a virtual machine or
container of some sort) or it may be remote (in a cloud). The communicator
interface abstracts this away so that communication is the same overall.
The documentation around the
[
code itself
](
https://github.com/mitchellh/packer/blob/master/packer/communicator.go
)
is really great as an overview of how to use the interface. You should begin
by reading this. Once you have read it, you can see some example usage below:
<pre
class=
"prettyprint"
>
// Build the remote command.
var cmd packer.RemoteCmd
cmd.Command = "echo foo"
// We care about stdout, so lets collect that into a buffer. Since
// we don't set stderr, that will just be discarded.
var stdout bytes.Buffer
cmd.Stdout = &stdout
// Start the command
if err := comm.Start(
&cmd);
err != nil {
panic(err)
}
// Wait for it to complete
cmd.Wait()
// Read the stdout!
fmt.Printf("Command output: %s", stdout.String())
</pre>
website/source/layouts/docs.erb
View file @
25afaf83
...
...
@@ -63,7 +63,7 @@
<li><a
href=
"/docs/extend/builder.html"
>
Custom Builder
</a></li>
<li><a
href=
"/docs/extend/command.html"
>
Custom Command
</a></li>
<li><a
href=
"/docs/extend/post-processor.html"
>
Custom Post-Processor
</a></li>
<li><a
href=
"
#
"
>
Custom Provisioner
</a></li>
<li><a
href=
"
/docs/extend/provisioner.html
"
>
Custom Provisioner
</a></li>
</ul>
</div>
<!--/.well -->
</div>
<!--/span-->
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment