golang 1.14 doesn't like calling NewFile on existing files. Port solution over from Terraform
This commit is contained in:
parent
73c349d09c
commit
217dcbb97f
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/chzyer/readline"
|
||||
"github.com/hashicorp/packer/helper/wrappedreadline"
|
||||
"github.com/hashicorp/packer/helper/wrappedstreams"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
|
@ -115,7 +116,7 @@ func (*ConsoleCommand) AutocompleteFlags() complete.Flags {
|
|||
|
||||
func (c *ConsoleCommand) modePiped(session *REPLSession) int {
|
||||
var lastResult string
|
||||
scanner := bufio.NewScanner(wrappedreadline.Stdin())
|
||||
scanner := bufio.NewScanner(wrappedstreams.Stdin())
|
||||
for scanner.Scan() {
|
||||
result, err := session.Handle(strings.TrimSpace(scanner.Text()))
|
||||
if err != nil {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
kvflag "github.com/hashicorp/packer/helper/flag-kv"
|
||||
sliceflag "github.com/hashicorp/packer/helper/flag-slice"
|
||||
"github.com/hashicorp/packer/helper/wrappedreadline"
|
||||
"github.com/hashicorp/packer/helper/wrappedstreams"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template"
|
||||
)
|
||||
|
@ -166,7 +166,7 @@ func (m *Meta) ValidateFlags() error {
|
|||
|
||||
// StdinPiped returns true if the input is piped.
|
||||
func (m *Meta) StdinPiped() bool {
|
||||
fi, err := wrappedreadline.Stdin().Stat()
|
||||
fi, err := wrappedstreams.Stdin().Stat()
|
||||
if err != nil {
|
||||
// If there is an error, let's just say its not piped
|
||||
return false
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Shamelessly copied from the Terraform repo because it wasn't worth vendoring
|
||||
// out two hundred lines of code so Packer could use it too.
|
||||
// STOLEN SHAMELESSLY FROM THE TERRAFORM REPO BECAUSE VENDORING OUT
|
||||
// WRAPPEDREADLINE AND WRAPPEDSTREAMS FELT LIKE TOO MUCH WORK.
|
||||
//
|
||||
// "a little copying is better than a lot of dependency"
|
||||
//
|
||||
// wrappedreadline is a package that has helpers for interacting with
|
||||
// readline from a panicwrap executable.
|
||||
|
@ -13,24 +15,24 @@
|
|||
package wrappedreadline
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/chzyer/readline"
|
||||
"github.com/mitchellh/panicwrap"
|
||||
|
||||
"github.com/hashicorp/packer/helper/wrappedstreams"
|
||||
)
|
||||
|
||||
// Override overrides the values in readline.Config that need to be
|
||||
// set with wrapped values.
|
||||
func Override(cfg *readline.Config) *readline.Config {
|
||||
cfg.Stdin = Stdin()
|
||||
cfg.Stdout = Stdout()
|
||||
cfg.Stderr = Stderr()
|
||||
cfg.Stdin = wrappedstreams.Stdin()
|
||||
cfg.Stdout = wrappedstreams.Stdout()
|
||||
cfg.Stderr = wrappedstreams.Stderr()
|
||||
|
||||
cfg.FuncGetWidth = TerminalWidth
|
||||
cfg.FuncIsTerminal = IsTerminal
|
||||
|
||||
rm := RawMode{StdinFd: int(Stdin().Fd())}
|
||||
rm := RawMode{StdinFd: int(wrappedstreams.Stdin().Fd())}
|
||||
cfg.FuncMakeRaw = rm.Enter
|
||||
cfg.FuncExitRaw = rm.Exit
|
||||
|
||||
|
@ -45,9 +47,9 @@ func IsTerminal() bool {
|
|||
}
|
||||
|
||||
// Same implementation as readline but with our custom fds
|
||||
return readline.IsTerminal(int(Stdin().Fd())) &&
|
||||
(readline.IsTerminal(int(Stdout().Fd())) ||
|
||||
readline.IsTerminal(int(Stderr().Fd())))
|
||||
return readline.IsTerminal(int(wrappedstreams.Stdin().Fd())) &&
|
||||
(readline.IsTerminal(int(wrappedstreams.Stdout().Fd())) ||
|
||||
readline.IsTerminal(int(wrappedstreams.Stderr().Fd())))
|
||||
}
|
||||
|
||||
// TerminalWidth gets the terminal width in characters.
|
||||
|
@ -78,43 +80,3 @@ func (r *RawMode) Exit() error {
|
|||
|
||||
return readline.Restore(r.StdinFd, r.state)
|
||||
}
|
||||
|
||||
// Package provides access to the standard OS streams
|
||||
// (stdin, stdout, stderr) even if wrapped under panicwrap.
|
||||
// Stdin returns the true stdin of the process.
|
||||
func Stdin() *os.File {
|
||||
stdin := os.Stdin
|
||||
if panicwrap.Wrapped(nil) {
|
||||
stdin = wrappedStdin
|
||||
}
|
||||
|
||||
return stdin
|
||||
}
|
||||
|
||||
// Stdout returns the true stdout of the process.
|
||||
func Stdout() *os.File {
|
||||
stdout := os.Stdout
|
||||
if panicwrap.Wrapped(nil) {
|
||||
stdout = wrappedStdout
|
||||
}
|
||||
|
||||
return stdout
|
||||
}
|
||||
|
||||
// Stderr returns the true stderr of the process.
|
||||
func Stderr() *os.File {
|
||||
stderr := os.Stderr
|
||||
if panicwrap.Wrapped(nil) {
|
||||
stderr = wrappedStderr
|
||||
}
|
||||
|
||||
return stderr
|
||||
}
|
||||
|
||||
// These are the wrapped standard streams. These are setup by the
|
||||
// platform specific code in initPlatform.
|
||||
var (
|
||||
wrappedStdin *os.File
|
||||
wrappedStdout *os.File
|
||||
wrappedStderr *os.File
|
||||
)
|
||||
|
|
|
@ -3,15 +3,16 @@
|
|||
package wrappedreadline
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/hashicorp/packer/helper/wrappedstreams"
|
||||
)
|
||||
|
||||
// getWidth impl for Unix
|
||||
func getWidth() int {
|
||||
stdoutFd := int(Stdout().Fd())
|
||||
stderrFd := int(Stderr().Fd())
|
||||
stdoutFd := int(wrappedstreams.Stdout().Fd())
|
||||
stderrFd := int(wrappedstreams.Stderr().Fd())
|
||||
|
||||
w := getWidthFd(stdoutFd)
|
||||
if w < 0 {
|
||||
|
@ -43,10 +44,3 @@ func getWidthFd(stdoutFd int) int {
|
|||
|
||||
return int(ws.Col)
|
||||
}
|
||||
|
||||
func init() {
|
||||
// The standard streams are passed in via extra file descriptors.
|
||||
wrappedStdin = os.NewFile(uintptr(3), "stdin")
|
||||
wrappedStdout = os.NewFile(uintptr(4), "stdout")
|
||||
wrappedStderr = os.NewFile(uintptr(5), "stderr")
|
||||
}
|
||||
|
|
|
@ -2,56 +2,7 @@
|
|||
|
||||
package wrappedreadline
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// getWidth impl for other
|
||||
func getWidth() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
wrappedStdin = openConsole("CONIN$", os.Stdin)
|
||||
wrappedStdout = openConsole("CONOUT$", os.Stdout)
|
||||
wrappedStderr = wrappedStdout
|
||||
}
|
||||
|
||||
// openConsole opens a console handle, using a backup if it fails.
|
||||
// This is used to get the exact console handle instead of the redirected
|
||||
// handles from panicwrap.
|
||||
func openConsole(name string, backup *os.File) *os.File {
|
||||
// Convert to UTF16
|
||||
path, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] wrappedstreams: %s", err)
|
||||
return backup
|
||||
}
|
||||
|
||||
// Determine the share mode
|
||||
var shareMode uint32
|
||||
switch name {
|
||||
case "CONIN$":
|
||||
shareMode = syscall.FILE_SHARE_READ
|
||||
case "CONOUT$":
|
||||
shareMode = syscall.FILE_SHARE_WRITE
|
||||
}
|
||||
|
||||
// Get the file
|
||||
h, err := syscall.CreateFile(
|
||||
path,
|
||||
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
|
||||
shareMode,
|
||||
nil,
|
||||
syscall.OPEN_EXISTING,
|
||||
0, 0)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] wrappedstreams: %s", err)
|
||||
return backup
|
||||
}
|
||||
|
||||
// Create the Go file
|
||||
return os.NewFile(uintptr(h), name)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// STOLEN SHAMELESSLY FROM THE TERRAFORM REPO BECAUSE VENDORING OUT
|
||||
// WRAPPEDREADLINE AND WRAPPEDSTREAMS FELT LIKE TOO MUCH WORK.
|
||||
//
|
||||
// "a little copying is better than a lot of dependency"
|
||||
//
|
||||
// Package wrappedstreams provides access to the standard OS streams
|
||||
// (stdin, stdout, stderr) even if wrapped under panicwrap.
|
||||
package wrappedstreams
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/mitchellh/panicwrap"
|
||||
)
|
||||
|
||||
// Stdin returns the true stdin of the process.
|
||||
func Stdin() *os.File {
|
||||
stdin, _, _ := fds()
|
||||
return stdin
|
||||
}
|
||||
|
||||
// Stdout returns the true stdout of the process.
|
||||
func Stdout() *os.File {
|
||||
_, stdout, _ := fds()
|
||||
return stdout
|
||||
}
|
||||
|
||||
// Stderr returns the true stderr of the process.
|
||||
func Stderr() *os.File {
|
||||
_, _, stderr := fds()
|
||||
return stderr
|
||||
}
|
||||
|
||||
func fds() (stdin, stdout, stderr *os.File) {
|
||||
stdin, stdout, stderr = os.Stdin, os.Stdout, os.Stderr
|
||||
if panicwrap.Wrapped(nil) {
|
||||
initPlatform()
|
||||
stdin, stdout, stderr = wrappedStdin, wrappedStdout, wrappedStderr
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// These are the wrapped standard streams. These are setup by the
|
||||
// platform specific code in initPlatform.
|
||||
var (
|
||||
wrappedStdin *os.File
|
||||
wrappedStdout *os.File
|
||||
wrappedStderr *os.File
|
||||
)
|
|
@ -0,0 +1,21 @@
|
|||
// +build !windows
|
||||
|
||||
package wrappedstreams
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var initOnce sync.Once
|
||||
|
||||
func initPlatform() {
|
||||
// These must be initialized lazily, once it's been determined that this is
|
||||
// a wrapped process.
|
||||
initOnce.Do(func() {
|
||||
// The standard streams are passed in via extra file descriptors.
|
||||
wrappedStdin = os.NewFile(uintptr(3), "stdin")
|
||||
wrappedStdout = os.NewFile(uintptr(4), "stdout")
|
||||
wrappedStderr = os.NewFile(uintptr(5), "stderr")
|
||||
})
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
// +build windows
|
||||
|
||||
package wrappedstreams
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func initPlatform() {
|
||||
wrappedStdin = openConsole("CONIN$", os.Stdin)
|
||||
wrappedStdout = openConsole("CONOUT$", os.Stdout)
|
||||
wrappedStderr = wrappedStdout
|
||||
}
|
||||
|
||||
// openConsole opens a console handle, using a backup if it fails.
|
||||
// This is used to get the exact console handle instead of the redirected
|
||||
// handles from panicwrap.
|
||||
func openConsole(name string, backup *os.File) *os.File {
|
||||
// Convert to UTF16
|
||||
path, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] wrappedstreams: %s", err)
|
||||
return backup
|
||||
}
|
||||
|
||||
// Determine the share mode
|
||||
var shareMode uint32
|
||||
switch name {
|
||||
case "CONIN$":
|
||||
shareMode = syscall.FILE_SHARE_READ
|
||||
case "CONOUT$":
|
||||
shareMode = syscall.FILE_SHARE_WRITE
|
||||
}
|
||||
|
||||
// Get the file
|
||||
h, err := syscall.CreateFile(
|
||||
path,
|
||||
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
|
||||
shareMode,
|
||||
nil,
|
||||
syscall.OPEN_EXISTING,
|
||||
0, 0)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] wrappedstreams: %s", err)
|
||||
return backup
|
||||
}
|
||||
|
||||
// Create the Go file
|
||||
return os.NewFile(uintptr(h), name)
|
||||
}
|
Loading…
Reference in New Issue