From c74b3758d32c073973512dea13c4703043245f1c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 1 Jan 2014 20:55:08 -0800 Subject: [PATCH 1/3] builder/vmware-iso: ESX5Driver impl OutputDir [GH-773] --- CHANGELOG.md | 1 + builder/vmware/iso/driver_esx5.go | 8 ++++++++ builder/vmware/iso/driver_esx5_test.go | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00ae24d1e..dde55505b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ BUG FIXES: * core: If a stream ID loops around, don't let it use stream ID 0 [GH-767] * 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) diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index 09083d618..4226652ad 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -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) } diff --git a/builder/vmware/iso/driver_esx5_test.go b/builder/vmware/iso/driver_esx5_test.go index c7e4f776d..6c3cd23e2 100644 --- a/builder/vmware/iso/driver_esx5_test.go +++ b/builder/vmware/iso/driver_esx5_test.go @@ -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) } From 21b690851f14b1aca7869099b21688cea2816429 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 1 Jan 2014 21:19:47 -0800 Subject: [PATCH 2/3] fmt --- packer/rpc/muxconn.go | 460 +++++++++++++++++++++--------------------- 1 file changed, 230 insertions(+), 230 deletions(-) diff --git a/packer/rpc/muxconn.go b/packer/rpc/muxconn.go index 956e21aed..2031ec5cb 100644 --- a/packer/rpc/muxconn.go +++ b/packer/rpc/muxconn.go @@ -319,263 +319,263 @@ func (m *MuxConn) loop() { log.Printf( "[WARN] %p: Non-existent stream %d (%s) received packer %d", m, id, from, packetType) - continue - } - - //log.Printf("[TRACE] %p: Stream %d (%s) received packet %d", m, id, from, packetType) - switch packetType { - case muxPacketSyn: - // If the stream is nil, this is the only case where we'll - // automatically create the stream struct. - if stream == nil { - var ok bool - - m.muAccept.Lock() - stream, ok = m.streamsAccept[id] - if !ok { - stream = newStream(muxPacketFromAccept, id, m) - m.streamsAccept[id] = stream - } - m.muAccept.Unlock() - } + continue + } - stream.mu.Lock() - switch stream.state { - case streamStateClosed: - fallthrough - case streamStateListen: - stream.setState(streamStateSynRecv) - default: - log.Printf("[ERR] Syn received for stream in state: %d", stream.state) - } - stream.mu.Unlock() - case muxPacketAck: - stream.mu.Lock() - switch stream.state { - case streamStateSynRecv: - stream.setState(streamStateEstablished) - case streamStateFinWait1: - stream.setState(streamStateFinWait2) - case streamStateLastAck: - stream.closeWriter() - fallthrough - case streamStateClosing: - stream.setState(streamStateClosed) - default: - log.Printf("[ERR] Ack received for stream in state: %d", stream.state) - } - stream.mu.Unlock() - case muxPacketSynAck: - stream.mu.Lock() - switch stream.state { - case streamStateSynSent: - stream.setState(streamStateEstablished) - default: - log.Printf("[ERR] SynAck received for stream in state: %d", stream.state) - } - stream.mu.Unlock() - case muxPacketFin: - stream.mu.Lock() - switch stream.state { - case streamStateEstablished: - stream.closeWriter() - stream.setState(streamStateCloseWait) - stream.write(muxPacketAck, nil) - case streamStateFinWait2: - stream.closeWriter() - stream.setState(streamStateClosed) - stream.write(muxPacketAck, nil) - case streamStateFinWait1: - stream.closeWriter() - stream.setState(streamStateClosing) - stream.write(muxPacketAck, nil) - default: - log.Printf("[ERR] Fin received for stream %d in state: %d", id, stream.state) - } - stream.mu.Unlock() - - case muxPacketData: - stream.mu.Lock() - switch stream.state { - case streamStateFinWait1: - fallthrough - case streamStateFinWait2: - fallthrough - case streamStateEstablished: - if len(data) > 0 { - select { - case stream.writeCh <- data: - default: - panic(fmt.Sprintf( - "Failed to write data, buffer full for stream %d", id)) - } - } - default: - log.Printf("[ERR] Data received for stream in state: %d", stream.state) - } - stream.mu.Unlock() + //log.Printf("[TRACE] %p: Stream %d (%s) received packet %d", m, id, from, packetType) + switch packetType { + case muxPacketSyn: + // If the stream is nil, this is the only case where we'll + // automatically create the stream struct. + if stream == nil { + var ok bool + + m.muAccept.Lock() + stream, ok = m.streamsAccept[id] + if !ok { + stream = newStream(muxPacketFromAccept, id, m) + m.streamsAccept[id] = stream } + m.muAccept.Unlock() } - } - func (m *MuxConn) write(from muxPacketFrom, id uint32, dataType muxPacketType, p []byte) (int, error) { - m.wlock.Lock() - defer m.wlock.Unlock() - - if err := binary.Write(m.rwc, binary.BigEndian, from); err != nil { - return 0, err + stream.mu.Lock() + switch stream.state { + case streamStateClosed: + fallthrough + case streamStateListen: + stream.setState(streamStateSynRecv) + default: + log.Printf("[ERR] Syn received for stream in state: %d", stream.state) } - if err := binary.Write(m.rwc, binary.BigEndian, id); err != nil { - return 0, err + stream.mu.Unlock() + case muxPacketAck: + stream.mu.Lock() + switch stream.state { + case streamStateSynRecv: + stream.setState(streamStateEstablished) + case streamStateFinWait1: + stream.setState(streamStateFinWait2) + case streamStateLastAck: + stream.closeWriter() + fallthrough + case streamStateClosing: + stream.setState(streamStateClosed) + default: + log.Printf("[ERR] Ack received for stream in state: %d", stream.state) } - if err := binary.Write(m.rwc, binary.BigEndian, byte(dataType)); err != nil { - return 0, err + stream.mu.Unlock() + case muxPacketSynAck: + stream.mu.Lock() + switch stream.state { + case streamStateSynSent: + stream.setState(streamStateEstablished) + default: + log.Printf("[ERR] SynAck received for stream in state: %d", stream.state) } - if err := binary.Write(m.rwc, binary.BigEndian, int32(len(p))); err != nil { - return 0, err + stream.mu.Unlock() + case muxPacketFin: + stream.mu.Lock() + switch stream.state { + case streamStateEstablished: + stream.closeWriter() + stream.setState(streamStateCloseWait) + stream.write(muxPacketAck, nil) + case streamStateFinWait2: + stream.closeWriter() + stream.setState(streamStateClosed) + stream.write(muxPacketAck, nil) + case streamStateFinWait1: + stream.closeWriter() + stream.setState(streamStateClosing) + stream.write(muxPacketAck, nil) + default: + log.Printf("[ERR] Fin received for stream %d in state: %d", id, stream.state) } - if len(p) == 0 { - return 0, nil + stream.mu.Unlock() + + case muxPacketData: + stream.mu.Lock() + switch stream.state { + case streamStateFinWait1: + fallthrough + case streamStateFinWait2: + fallthrough + case streamStateEstablished: + if len(data) > 0 { + select { + case stream.writeCh <- data: + default: + panic(fmt.Sprintf( + "Failed to write data, buffer full for stream %d", id)) + } + } + default: + log.Printf("[ERR] Data received for stream in state: %d", stream.state) } - return m.rwc.Write(p) + stream.mu.Unlock() } + } +} - // Stream is a single stream of data and implements io.ReadWriteCloser. - // A Stream is full-duplex so you can write data as well as read data. - type Stream struct { - from muxPacketFrom - id uint32 - mux *MuxConn - reader io.Reader - state streamState - stateChange map[chan<- streamState]struct{} - stateUpdated time.Time - mu sync.Mutex - writeCh chan<- []byte - } +func (m *MuxConn) write(from muxPacketFrom, id uint32, dataType muxPacketType, p []byte) (int, error) { + m.wlock.Lock() + defer m.wlock.Unlock() - type streamState byte - - const ( - streamStateClosed streamState = iota - streamStateListen - streamStateSynRecv - streamStateSynSent - streamStateEstablished - streamStateFinWait1 - streamStateFinWait2 - streamStateCloseWait - streamStateClosing - streamStateLastAck - ) - - func newStream(from muxPacketFrom, id uint32, m *MuxConn) *Stream { - // Create the stream object and channel where data will be sent to - dataR, dataW := io.Pipe() - writeCh := make(chan []byte, 4096) - - // Set the data channel so we can write to it. - stream := &Stream{ - from: from, - id: id, - mux: m, - reader: dataR, - writeCh: writeCh, - stateChange: make(map[chan<- streamState]struct{}), - } - stream.setState(streamStateClosed) - - // Start the goroutine that will read from the queue and write - // data out. - go func() { - defer dataW.Close() - - for { - data := <-writeCh - if data == nil { - // A nil is a tombstone letting us know we're done - // accepting data. - return - } + if err := binary.Write(m.rwc, binary.BigEndian, from); err != nil { + return 0, err + } + if err := binary.Write(m.rwc, binary.BigEndian, id); err != nil { + return 0, err + } + if err := binary.Write(m.rwc, binary.BigEndian, byte(dataType)); err != nil { + return 0, err + } + if err := binary.Write(m.rwc, binary.BigEndian, int32(len(p))); err != nil { + return 0, err + } + if len(p) == 0 { + return 0, nil + } + return m.rwc.Write(p) +} - if _, err := dataW.Write(data); err != nil { - return - } - } - }() +// Stream is a single stream of data and implements io.ReadWriteCloser. +// A Stream is full-duplex so you can write data as well as read data. +type Stream struct { + from muxPacketFrom + id uint32 + mux *MuxConn + reader io.Reader + state streamState + stateChange map[chan<- streamState]struct{} + stateUpdated time.Time + mu sync.Mutex + writeCh chan<- []byte +} - return stream - } +type streamState byte - func (s *Stream) Close() error { - s.mu.Lock() - defer s.mu.Unlock() +const ( + streamStateClosed streamState = iota + streamStateListen + streamStateSynRecv + streamStateSynSent + streamStateEstablished + streamStateFinWait1 + streamStateFinWait2 + streamStateCloseWait + streamStateClosing + streamStateLastAck +) - if s.state != streamStateEstablished && s.state != streamStateCloseWait { - return fmt.Errorf("Stream in bad state: %d", s.state) +func newStream(from muxPacketFrom, id uint32, m *MuxConn) *Stream { + // Create the stream object and channel where data will be sent to + dataR, dataW := io.Pipe() + writeCh := make(chan []byte, 4096) + + // Set the data channel so we can write to it. + stream := &Stream{ + from: from, + id: id, + mux: m, + reader: dataR, + writeCh: writeCh, + stateChange: make(map[chan<- streamState]struct{}), + } + stream.setState(streamStateClosed) + + // Start the goroutine that will read from the queue and write + // data out. + go func() { + defer dataW.Close() + + for { + data := <-writeCh + if data == nil { + // A nil is a tombstone letting us know we're done + // accepting data. + return } - if s.state == streamStateEstablished { - s.setState(streamStateFinWait1) - } else { - s.setState(streamStateLastAck) + if _, err := dataW.Write(data); err != nil { + return } - - s.write(muxPacketFin, nil) - return nil } + }() - func (s *Stream) Read(p []byte) (int, error) { - return s.reader.Read(p) - } + return stream +} - func (s *Stream) Write(p []byte) (int, error) { - s.mu.Lock() - state := s.state - s.mu.Unlock() +func (s *Stream) Close() error { + s.mu.Lock() + defer s.mu.Unlock() - if state != streamStateEstablished && state != streamStateCloseWait { - return 0, fmt.Errorf("Stream %d in bad state to send: %d", s.id, state) - } + if s.state != streamStateEstablished && s.state != streamStateCloseWait { + return fmt.Errorf("Stream in bad state: %d", s.state) + } - return s.write(muxPacketData, p) - } + if s.state == streamStateEstablished { + s.setState(streamStateFinWait1) + } else { + s.setState(streamStateLastAck) + } - func (s *Stream) closeWriter() { - s.writeCh <- nil - } + s.write(muxPacketFin, nil) + return nil +} - func (s *Stream) setState(state streamState) { - //log.Printf("[TRACE] %p: Stream %d (%s) went to state %d", s.mux, s.id, s.from, state) - s.state = state - s.stateUpdated = time.Now().UTC() - for ch, _ := range s.stateChange { - select { - case ch <- state: - default: - } - } - } +func (s *Stream) Read(p []byte) (int, error) { + return s.reader.Read(p) +} - func (s *Stream) waitState(target streamState) error { - // Register a state change listener to wait for changes - stateCh := make(chan streamState, 10) - s.stateChange[stateCh] = struct{}{} - s.mu.Unlock() +func (s *Stream) Write(p []byte) (int, error) { + s.mu.Lock() + state := s.state + s.mu.Unlock() - defer func() { - s.mu.Lock() - delete(s.stateChange, stateCh) - }() - - state := <-stateCh - if state == target { - return nil - } else { - return fmt.Errorf("Stream %d went to bad state: %d", s.id, state) - } - } + if state != streamStateEstablished && state != streamStateCloseWait { + return 0, fmt.Errorf("Stream %d in bad state to send: %d", s.id, state) + } - func (s *Stream) write(dataType muxPacketType, p []byte) (int, error) { - return s.mux.write(s.from, s.id, dataType, p) + return s.write(muxPacketData, p) +} + +func (s *Stream) closeWriter() { + s.writeCh <- nil +} + +func (s *Stream) setState(state streamState) { + //log.Printf("[TRACE] %p: Stream %d (%s) went to state %d", s.mux, s.id, s.from, state) + s.state = state + s.stateUpdated = time.Now().UTC() + for ch, _ := range s.stateChange { + select { + case ch <- state: + default: } + } +} + +func (s *Stream) waitState(target streamState) error { + // Register a state change listener to wait for changes + stateCh := make(chan streamState, 10) + s.stateChange[stateCh] = struct{}{} + s.mu.Unlock() + + defer func() { + s.mu.Lock() + delete(s.stateChange, stateCh) + }() + + state := <-stateCh + if state == target { + return nil + } else { + return fmt.Errorf("Stream %d went to bad state: %d", s.id, state) + } +} + +func (s *Stream) write(dataType muxPacketType, p []byte) (int, error) { + return s.mux.write(s.from, s.id, dataType, p) +} From 3a1908bbb36f978dcbff7bce4030b52a88f4d16d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 1 Jan 2014 21:34:11 -0800 Subject: [PATCH 3/3] packer/rpc: make things loud --- packer/rpc/muxconn.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packer/rpc/muxconn.go b/packer/rpc/muxconn.go index 2031ec5cb..d03c68c6b 100644 --- a/packer/rpc/muxconn.go +++ b/packer/rpc/muxconn.go @@ -100,7 +100,7 @@ func (m *MuxConn) Close() error { // Accept accepts a multiplexed connection with the given ID. This // will block until a request is made to connect. func (m *MuxConn) Accept(id uint32) (io.ReadWriteCloser, error) { - //log.Printf("[TRACE] %p: Accept on stream ID: %d", m, id) + log.Printf("[TRACE] %p: Accept on stream ID: %d", m, id) // Get the stream. It is okay if it is already in the list of streams // because we may have prematurely received a syn for it. @@ -322,7 +322,7 @@ func (m *MuxConn) loop() { continue } - //log.Printf("[TRACE] %p: Stream %d (%s) received packet %d", m, id, from, packetType) + log.Printf("[TRACE] %p: Stream %d (%s) received packet %d", m, id, from, packetType) switch packetType { case muxPacketSyn: // If the stream is nil, this is the only case where we'll @@ -546,7 +546,7 @@ func (s *Stream) closeWriter() { } func (s *Stream) setState(state streamState) { - //log.Printf("[TRACE] %p: Stream %d (%s) went to state %d", s.mux, s.id, s.from, state) + log.Printf("[TRACE] %p: Stream %d (%s) went to state %d", s.mux, s.id, s.from, state) s.state = state s.stateUpdated = time.Now().UTC() for ch, _ := range s.stateChange {