Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d1cc53d45 | |||
| 377f7ba3cd | |||
| 57c53ea2d7 | |||
| 5ad40dd184 | |||
| a35cbfc4da | |||
| 86df78a7be | |||
| 958502bbdc | |||
| 014ed0e507 | |||
| 45f6f6f297 | |||
| 7c7a8a7f27 | |||
| 1beec2b713 | |||
| 42d0980228 | |||
| a45f843ccb | |||
| f3bcdbdf34 | |||
| bb1aae39b0 | |||
| 2e1032a36b | |||
| f3ece7ceae | |||
| 0543d238dd | |||
| c420dc6e19 | |||
| 15206f53e8 | |||
| b4cca743cf | |||
| c3bbb82c5c | |||
| 32f6dd17a3 | |||
| c3363e48ed |
@@ -1,3 +1,22 @@
|
||||
## 0.1.2 (June 29, 2013)
|
||||
|
||||
IMPROVEMENTS:
|
||||
|
||||
* core: Template doesn't validate if there are no builders.
|
||||
* vmware: Delete any VMware files in the VM that aren't necessary for
|
||||
it to function.
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* core: Plugin servers consider a port in use if there is any
|
||||
error listening to it. This fixes I18n issues and Windows. [GH-58]
|
||||
* amazon-ebs: Sleep between checking instance state to avoid
|
||||
RequestLimitExceeded [GH-50]
|
||||
* vagrant: Rename VirtualBox ovf to "box.ovf" [GH-64]
|
||||
* vagrant: VMware boxes have the correct provider type.
|
||||
* vmware: Properly populate files in artifact so that the Vagrant
|
||||
post-processor works. [GH-63]
|
||||
|
||||
## 0.1.1 (June 28, 2013)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
@@ -11,7 +11,9 @@ Packer is lightweight, runs on every major operating system, and is highly
|
||||
performant, creating machine images for multiple platforms in parallel.
|
||||
Packer comes out of the box with support for creating AMIs (EC2), VMware
|
||||
images, and VirtualBox images. Support for more platforms can be added via
|
||||
plugins. The images that Packer creates an easily be turned into
|
||||
plugins.
|
||||
|
||||
The images that Packer creates can easily be turned into
|
||||
[Vagrant](http://www.vagrantup.com) boxes.
|
||||
|
||||
## Quick Start
|
||||
@@ -78,5 +80,6 @@ $ bin/packer
|
||||
...
|
||||
```
|
||||
|
||||
You can run tests by typing `make test`. This will run tests for Packer core
|
||||
along with all the core builders and commands and such that come with Packer.
|
||||
You can run tests by typing `make test`.
|
||||
|
||||
This will run tests for Packer core along with all the core builders and commands and such that come with Packer.
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/mitchellh/goamz/ec2"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"strconv"
|
||||
"text/template"
|
||||
"time"
|
||||
@@ -68,6 +69,11 @@ func (s *stepCreateAMI) Run(state map[string]interface{}) multistep.StepAction {
|
||||
if imageResp.Images[0].State == "available" {
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("Image in state %s, sleeping 2s before checking again",
|
||||
imageResp.Images[0].State)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
|
||||
@@ -124,11 +124,13 @@ func (d *VBox42Driver) Version() (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Printf("VBoxManage --version output: %s", stdout.String())
|
||||
versionRe := regexp.MustCompile("[^.0-9]")
|
||||
matches := versionRe.Split(stdout.String(), 2)
|
||||
if len(matches) == 0 {
|
||||
return "", fmt.Errorf("No version found: %s", stdout.String())
|
||||
}
|
||||
|
||||
log.Printf("VirtualBox version: %s", matches[0])
|
||||
return matches[0], nil
|
||||
}
|
||||
|
||||
@@ -224,6 +224,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||
&stepWaitForSSH{},
|
||||
&stepProvision{},
|
||||
&stepShutdown{},
|
||||
&stepCleanFiles{},
|
||||
}
|
||||
|
||||
// Setup the state bag
|
||||
@@ -263,8 +264,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||
// Compile the artifact list
|
||||
files := make([]string, 0, 10)
|
||||
visit := func(path string, info os.FileInfo, err error) error {
|
||||
files = append(files, path)
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
files = append(files, path)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := filepath.Walk(b.config.OutputDir, visit); err != nil {
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package vmware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// These are the extensions of files that are important for the function
|
||||
// of a VMware virtual machine. Any other file is discarded as part of the
|
||||
// build.
|
||||
var KeepFileExtensions = []string{".nvram", ".vmdk", ".vmsd", ".vmx", ".vmxf"}
|
||||
|
||||
// This step removes unnecessary files from the final result.
|
||||
//
|
||||
// Uses:
|
||||
// config *config
|
||||
// ui packer.Ui
|
||||
//
|
||||
// Produces:
|
||||
// <nothing>
|
||||
type stepCleanFiles struct{}
|
||||
|
||||
func (stepCleanFiles) Run(state map[string]interface{}) multistep.StepAction {
|
||||
config := state["config"].(*config)
|
||||
ui := state["ui"].(packer.Ui)
|
||||
|
||||
ui.Say("Deleting unnecessary VMware files...")
|
||||
visit := func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
// If the file isn't critical to the function of the
|
||||
// virtual machine, we get rid of it.
|
||||
keep := false
|
||||
ext := filepath.Ext(path)
|
||||
for _, goodExt := range KeepFileExtensions {
|
||||
if goodExt == ext {
|
||||
keep = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !keep {
|
||||
ui.Message(fmt.Sprintf("Deleting: %s", path))
|
||||
return os.Remove(path)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := filepath.Walk(config.OutputDir, visit); err != nil {
|
||||
state["error"] = err
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (stepCleanFiles) Cleanup(map[string]interface{}) {}
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const MagicCookieKey = "PACKER_PLUGIN_MAGIC_COOKIE"
|
||||
@@ -59,14 +58,8 @@ func serve(server *rpc.Server) (err error) {
|
||||
address = fmt.Sprintf("127.0.0.1:%d", port)
|
||||
listener, err = net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "address already in use") {
|
||||
// Not an address already in use error, return.
|
||||
return
|
||||
} else {
|
||||
// Address is in use, just try another
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
@@ -172,6 +172,10 @@ func ParseTemplate(data []byte) (t *Template, err error) {
|
||||
raw.rawConfig = v
|
||||
}
|
||||
|
||||
if len(t.Builders) == 0 {
|
||||
errors = append(errors, fmt.Errorf("No builders are defined in the template."))
|
||||
}
|
||||
|
||||
// If there were errors, we put it into a MultiError and return
|
||||
if len(errors) > 0 {
|
||||
err = &MultiError{errors}
|
||||
|
||||
+12
-2
@@ -11,14 +11,14 @@ func TestParseTemplate_Basic(t *testing.T) {
|
||||
|
||||
data := `
|
||||
{
|
||||
"builders": []
|
||||
"builders": [{"type": "something"}]
|
||||
}
|
||||
`
|
||||
|
||||
result, err := ParseTemplate([]byte(data))
|
||||
assert.Nil(err, "should not error")
|
||||
assert.NotNil(result, "template should not be nil")
|
||||
assert.Length(result.Builders, 0, "no builders")
|
||||
assert.Length(result.Builders, 1, "one builder")
|
||||
}
|
||||
|
||||
func TestParseTemplate_Invalid(t *testing.T) {
|
||||
@@ -140,6 +140,8 @@ func TestParseTemplate_Hooks(t *testing.T) {
|
||||
data := `
|
||||
{
|
||||
|
||||
"builders": [{"type": "foo"}],
|
||||
|
||||
"hooks": {
|
||||
"event": ["foo", "bar"]
|
||||
}
|
||||
@@ -159,6 +161,8 @@ func TestParseTemplate_Hooks(t *testing.T) {
|
||||
func TestParseTemplate_PostProcessors(t *testing.T) {
|
||||
data := `
|
||||
{
|
||||
"builders": [{"type": "foo"}],
|
||||
|
||||
"post-processors": [
|
||||
"simple",
|
||||
|
||||
@@ -215,6 +219,8 @@ func TestParseTemplate_ProvisionerWithoutType(t *testing.T) {
|
||||
|
||||
data := `
|
||||
{
|
||||
"builders": [{"type": "foo"}],
|
||||
|
||||
"provisioners": [{}]
|
||||
}
|
||||
`
|
||||
@@ -228,6 +234,8 @@ func TestParseTemplate_ProvisionerWithNonStringType(t *testing.T) {
|
||||
|
||||
data := `
|
||||
{
|
||||
"builders": [{"type": "foo"}],
|
||||
|
||||
"provisioners": [{
|
||||
"type": 42
|
||||
}]
|
||||
@@ -243,6 +251,8 @@ func TestParseTemplate_Provisioners(t *testing.T) {
|
||||
|
||||
data := `
|
||||
{
|
||||
"builders": [{"type": "foo"}],
|
||||
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell"
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
// The version of packer.
|
||||
const Version = "0.1.1"
|
||||
const Version = "0.1.3"
|
||||
|
||||
// Any pre-release marker for the version. If this is "" (empty string),
|
||||
// then it means that it is a final release. Otherwise, this is the
|
||||
|
||||
@@ -111,6 +111,12 @@ func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifac
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Rename the OVF file to box.ovf, as required by Vagrant
|
||||
ui.Message("Renaming the OVF to box.ovf...")
|
||||
if err := p.renameOVF(dir); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compress the directory to the given output path
|
||||
ui.Message(fmt.Sprintf("Compressing box..."))
|
||||
if err := DirToBox(outputPath, dir); err != nil {
|
||||
@@ -156,6 +162,21 @@ func (p *VBoxBoxPostProcessor) findBaseMacAddress(a packer.Artifact) (string, er
|
||||
return string(matches[1]), nil
|
||||
}
|
||||
|
||||
func (p *VBoxBoxPostProcessor) renameOVF(dir string) error {
|
||||
log.Println("Looking for OVF to rename...")
|
||||
matches, err := filepath.Glob(filepath.Join(dir, "*.ovf"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(matches) > 1 {
|
||||
return errors.New("More than one OVF file in VirtualBox artifact.")
|
||||
}
|
||||
|
||||
log.Printf("Renaming: '%s' => box.ovf", matches[0])
|
||||
return os.Rename(matches[0], filepath.Join(dir, "box.ovf"))
|
||||
}
|
||||
|
||||
var defaultVBoxVagrantfile = `
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.base_mac = "{{ .BaseMacAddress }}"
|
||||
|
||||
@@ -88,7 +88,7 @@ func (p *VMwareBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artif
|
||||
}
|
||||
|
||||
// Create the metadata
|
||||
metadata := map[string]string{"provider": "vmware"}
|
||||
metadata := map[string]string{"provider": "vmware_desktop"}
|
||||
if err := WriteMetadata(dir, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ an Ubuntu 12.04 installer:
|
||||
"fb=false debconf/frontend=noninteractive ",
|
||||
"keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ",
|
||||
"keyboard-configuration/variant=USA console-setup/ask_detect=false ",
|
||||
"initrd=/install/initrd.gz -- <enter>"
|
||||
"initrd=/install/initrd.gz -- <enter>"
|
||||
]
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -180,6 +180,6 @@ an Ubuntu 12.04 installer:
|
||||
"fb=false debconf/frontend=noninteractive ",
|
||||
"keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ",
|
||||
"keyboard-configuration/variant=USA console-setup/ask_detect=false ",
|
||||
"initrd=/install/initrd.gz -- <enter>"
|
||||
"initrd=/install/initrd.gz -- <enter>"
|
||||
]
|
||||
</pre>
|
||||
|
||||
@@ -14,7 +14,7 @@ of templates that can be readily used with Packer by simply converting them.
|
||||
|
||||
## Installation and Usage
|
||||
|
||||
Since Veewee itself is a Ruby project, so to is the veewee-to-packer
|
||||
Since Veewee itself is a Ruby project, so too is the veewee-to-packer
|
||||
application so that it can read the Veewee configurations. Install it using RubyGems:
|
||||
|
||||
```
|
||||
|
||||
@@ -167,9 +167,11 @@ table {
|
||||
|
||||
::selection {
|
||||
background: #ffff00; /* Safari */
|
||||
color: $black;
|
||||
}
|
||||
::-moz-selection {
|
||||
background: #ffff00; /* Firefox */
|
||||
color: $black;
|
||||
}
|
||||
|
||||
input {
|
||||
|
||||
Reference in New Issue
Block a user