Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eeefde8fc7 | |||
| f325581bc2 | |||
| 356e872adb | |||
| b0d7933294 | |||
| c8ee2343c2 | |||
| c2cd1af775 | |||
| 73dc53dffb | |||
| f027418794 | |||
| 090718bd8e | |||
| 5fc3d67112 | |||
| a03283c3ab | |||
| f92e5d456d | |||
| e77671ea58 | |||
| 28c93dc1f2 | |||
| c29a068df2 | |||
| f381f04264 | |||
| fdf06a43b4 | |||
| c8d926b372 | |||
| 68062aed69 | |||
| 00cc9fb14c | |||
| 8dfb7842d4 | |||
| ae66764e92 | |||
| 188d4322c7 |
@@ -1,3 +1,13 @@
|
||||
## 0.5.1 (01/02/2014)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* core: If a stream ID loops around, don't let it use stream ID 0 [GH-767]
|
||||
* core: Fix issue where large writes to plugins would result in stream
|
||||
corruption. [GH-727]
|
||||
* builders/virtualbox-ovf: `shutdown_timeout` config works. [GH-772]
|
||||
* builders/vmware-iso: Remote driver works properly again. [GH-773]
|
||||
|
||||
## 0.5.0 (12/30/2013)
|
||||
|
||||
BACKWARDS INCOMPATIBILITIES:
|
||||
|
||||
@@ -51,6 +51,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(c.tpl)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(c.tpl)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(c.tpl)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(c.tpl)...)
|
||||
errs = packer.MultiErrorAppend(errs, c.VBoxVersionConfig.Prepare(c.tpl)...)
|
||||
|
||||
@@ -13,6 +13,19 @@ func testConfig(t *testing.T) map[string]interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
func getTempFile(t *testing.T) *os.File {
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
tf.Close()
|
||||
|
||||
// don't forget to cleanup the file downstream:
|
||||
// defer os.Remove(tf.Name())
|
||||
|
||||
return tf
|
||||
}
|
||||
|
||||
func testConfigErr(t *testing.T, warns []string, err error) {
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
@@ -45,11 +58,7 @@ func TestNewConfig_sourcePath(t *testing.T) {
|
||||
testConfigErr(t, warns, errs)
|
||||
|
||||
// Good
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
tf.Close()
|
||||
tf := getTempFile(t)
|
||||
defer os.Remove(tf.Name())
|
||||
|
||||
c = testConfig(t)
|
||||
@@ -57,3 +66,20 @@ func TestNewConfig_sourcePath(t *testing.T) {
|
||||
_, warns, errs = NewConfig(c)
|
||||
testConfigOk(t, warns, errs)
|
||||
}
|
||||
|
||||
func TestNewConfig_shutdown_timeout(t *testing.T) {
|
||||
c := testConfig(t)
|
||||
tf := getTempFile(t)
|
||||
defer os.Remove(tf.Name())
|
||||
|
||||
// Expect this to fail
|
||||
c["source_path"] = tf.Name()
|
||||
c["shutdown_timeout"] = "NaN"
|
||||
_, warns, errs := NewConfig(c)
|
||||
testConfigErr(t, warns, errs)
|
||||
|
||||
// Passes when given a valid time duration
|
||||
c["shutdown_timeout"] = "10s"
|
||||
_, warns, errs = NewConfig(c)
|
||||
testConfigOk(t, warns, errs)
|
||||
}
|
||||
|
||||
@@ -214,6 +214,10 @@ func (d *ESX5Driver) SSHAddress(state multistep.StateBag) (string, error) {
|
||||
return address, nil
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// OutputDir implementation
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
func (d *ESX5Driver) DirExists() (bool, error) {
|
||||
err := d.sh("test", "-e", d.outputDir)
|
||||
return err == nil, nil
|
||||
@@ -258,6 +262,10 @@ func (d *ESX5Driver) SetOutputDir(path string) {
|
||||
d.outputDir = d.datastorePath(path)
|
||||
}
|
||||
|
||||
func (d *ESX5Driver) String() string {
|
||||
return d.outputDir
|
||||
}
|
||||
|
||||
func (d *ESX5Driver) datastorePath(path string) string {
|
||||
return filepath.Join("/vmfs/volumes", d.Datastore, path)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@ func TestESX5Driver_implDriver(t *testing.T) {
|
||||
var _ vmwcommon.Driver = new(ESX5Driver)
|
||||
}
|
||||
|
||||
func TestESX5Driver_implOutputDir(t *testing.T) {
|
||||
var _ vmwcommon.OutputDir = new(ESX5Driver)
|
||||
}
|
||||
|
||||
func TestESX5Driver_implRemoteDriver(t *testing.T) {
|
||||
var _ RemoteDriver = new(ESX5Driver)
|
||||
}
|
||||
|
||||
+27
-11
@@ -146,6 +146,8 @@ func (m *MuxConn) Accept(id uint32) (io.ReadWriteCloser, error) {
|
||||
// Dial opens a connection to the remote end using the given stream ID.
|
||||
// An Accept on the remote end will only work with if the IDs match.
|
||||
func (m *MuxConn) Dial(id uint32) (io.ReadWriteCloser, error) {
|
||||
//log.Printf("[TRACE] %p: Dial on stream ID: %d", m, id)
|
||||
|
||||
m.muDial.Lock()
|
||||
|
||||
// If we have any streams with this ID, then it is a failure. The
|
||||
@@ -191,13 +193,13 @@ func (m *MuxConn) NextId() uint32 {
|
||||
m.muAccept.Lock()
|
||||
defer m.muAccept.Unlock()
|
||||
|
||||
// We never use stream ID 0 because 0 is the zero value of a uint32
|
||||
// and we want to reserve that for "not in use"
|
||||
if m.curId == 0 {
|
||||
m.curId = 1
|
||||
}
|
||||
|
||||
for {
|
||||
// We never use stream ID 0 because 0 is the zero value of a uint32
|
||||
// and we want to reserve that for "not in use"
|
||||
if m.curId == 0 {
|
||||
m.curId = 1
|
||||
}
|
||||
|
||||
result := m.curId
|
||||
m.curId += 1
|
||||
if _, ok := m.streamsAccept[result]; !ok {
|
||||
@@ -284,10 +286,13 @@ func (m *MuxConn) loop() {
|
||||
|
||||
// TODO(mitchellh): probably would be better to re-use a buffer...
|
||||
data := make([]byte, length)
|
||||
if length > 0 {
|
||||
if _, err := m.rwc.Read(data); err != nil {
|
||||
n := 0
|
||||
for n < int(length) {
|
||||
if n2, err := m.rwc.Read(data[n:]); err != nil {
|
||||
log.Printf("[ERR] Error reading data: %s", err)
|
||||
return
|
||||
} else {
|
||||
n += n2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,10 +439,21 @@ func (m *MuxConn) write(from muxPacketFrom, id uint32, dataType muxPacketType, p
|
||||
if err := binary.Write(m.rwc, binary.BigEndian, int32(len(p))); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return 0, nil
|
||||
|
||||
// Write all the bytes. If we don't write all the bytes, report an error
|
||||
var err error = nil
|
||||
n := 0
|
||||
for n < len(p) {
|
||||
var n2 int
|
||||
n2, err = m.rwc.Write(p[n:])
|
||||
n += n2
|
||||
if err != nil {
|
||||
log.Printf("[ERR] %p: Stream %d (%s) write error: %s", m, id, from, err)
|
||||
break
|
||||
}
|
||||
}
|
||||
return m.rwc.Write(p)
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Stream is a single stream of data and implements io.ReadWriteCloser.
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
||||
var GitCommit string
|
||||
|
||||
// The version of packer.
|
||||
const Version = "0.5.0"
|
||||
const Version = "0.5.1"
|
||||
|
||||
// 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
|
||||
|
||||
@@ -17,7 +17,7 @@ containers with portable scripts or configuration management systems
|
||||
that are not tied to Docker in any way. It also has a simpler mental model:
|
||||
you provision containers much the same way you provision a normal virtualized
|
||||
or dedicated server. For more information, read the section on
|
||||
[Dockerfiles](#toc_3).
|
||||
[Dockerfiles](#toc_4).
|
||||
|
||||
The Docker builder must run on a machine that has Docker installed. Therefore
|
||||
the builder only works on machines that support Docker (modern Linux machines).
|
||||
|
||||
@@ -86,8 +86,8 @@ for readability) to execute Puppet:
|
||||
{{.FacterVars}}{{if .Sudo}} sudo -E {{end}}puppet apply \
|
||||
--verbose \
|
||||
--modulepath='{{.ModulePath}}' \
|
||||
{{if .HieraConfigPath ne ""}}--hiera_config='{{.HieraConfigPath}}' {{end}} \
|
||||
{{if .ManifestDir ne ""}}--manifestdir='{{.ManifestDir}}' {{end}} \
|
||||
{{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}} \
|
||||
{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}} \
|
||||
{{.ManifestFile}}
|
||||
```
|
||||
|
||||
|
||||
@@ -36,9 +36,18 @@ the appropriate [documentation page within the documentation section](/docs).
|
||||
* ***DigitalOcean***. Snapshots for [DigitalOcean](http://www.digitalocean.com)
|
||||
that can be used to start a pre-configured DigitalOcean instance of any size.
|
||||
|
||||
* ***Docker***. Snapshots for [Docker](http://www.docker.io)
|
||||
that can be used to start a pre-configured Docker instance.
|
||||
|
||||
* ***Google Compute Engine***. Snapshots for [Google Compute Engine](https://cloud.google.com/products/compute-engine)
|
||||
that can be used to start a pre-configured Google Compute Engine instance.
|
||||
|
||||
* ***OpenStack***. Images for [OpenStack](http://www.openstack.org)
|
||||
that can be used to start pre-configured OpenStack servers.
|
||||
|
||||
* ***QEMU***. Images for [KVM](http://www.linux-kvm.org/) or [Xen](http://www.xenproject.org/)
|
||||
that can be used to start pre-configured KVM or Xen instances.
|
||||
|
||||
* ***VirtualBox (OVF)***. Exported virtual machines for VirtualBox, including
|
||||
virtual machine metadata such as RAM, CPUs, etc. These virtual machines are
|
||||
portable and can be started on any platform VirtualBox runs on.
|
||||
|
||||
Reference in New Issue
Block a user