2018-02-05 16:13:06 -05:00
|
|
|
// +build linux darwin freebsd netbsd openbsd solaris dragonfly
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
// +build !appengine !js
|
2018-02-05 16:13:06 -05:00
|
|
|
|
|
|
|
package pb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"sync"
|
|
|
|
"syscall"
|
|
|
|
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
)
|
|
|
|
|
|
|
|
var ErrPoolWasStarted = errors.New("Bar pool was started")
|
|
|
|
|
|
|
|
var (
|
|
|
|
echoLockMutex sync.Mutex
|
|
|
|
origTermStatePtr *unix.Termios
|
|
|
|
tty *os.File
|
2018-10-16 12:18:29 -04:00
|
|
|
istty bool
|
2018-02-05 16:13:06 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
echoLockMutex.Lock()
|
|
|
|
defer echoLockMutex.Unlock()
|
|
|
|
|
|
|
|
var err error
|
|
|
|
tty, err = os.Open("/dev/tty")
|
2018-10-16 12:18:29 -04:00
|
|
|
istty = true
|
2018-02-05 16:13:06 -05:00
|
|
|
if err != nil {
|
|
|
|
tty = os.Stdin
|
2018-10-16 12:18:29 -04:00
|
|
|
istty = false
|
2018-02-05 16:13:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// terminalWidth returns width of the terminal.
|
|
|
|
func terminalWidth() (int, error) {
|
2018-10-16 12:18:29 -04:00
|
|
|
if !istty {
|
|
|
|
return 0, errors.New("Not Supported")
|
|
|
|
}
|
2018-02-05 16:13:06 -05:00
|
|
|
echoLockMutex.Lock()
|
|
|
|
defer echoLockMutex.Unlock()
|
|
|
|
|
|
|
|
fd := int(tty.Fd())
|
|
|
|
|
|
|
|
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return int(ws.Col), nil
|
|
|
|
}
|
|
|
|
|
2018-04-27 02:20:56 -04:00
|
|
|
func lockEcho() (shutdownCh chan struct{}, err error) {
|
2018-02-05 16:13:06 -05:00
|
|
|
echoLockMutex.Lock()
|
|
|
|
defer echoLockMutex.Unlock()
|
2018-10-16 12:18:29 -04:00
|
|
|
if istty {
|
|
|
|
if origTermStatePtr != nil {
|
|
|
|
return shutdownCh, ErrPoolWasStarted
|
|
|
|
}
|
|
|
|
|
|
|
|
fd := int(tty.Fd())
|
|
|
|
|
|
|
|
origTermStatePtr, err = unix.IoctlGetTermios(fd, ioctlReadTermios)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Can't get terminal settings: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
oldTermios := *origTermStatePtr
|
|
|
|
newTermios := oldTermios
|
|
|
|
newTermios.Lflag &^= syscall.ECHO
|
|
|
|
newTermios.Lflag |= syscall.ICANON | syscall.ISIG
|
|
|
|
newTermios.Iflag |= syscall.ICRNL
|
|
|
|
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newTermios); err != nil {
|
|
|
|
return nil, fmt.Errorf("Can't set terminal settings: %v", err)
|
|
|
|
}
|
2018-02-05 16:13:06 -05:00
|
|
|
|
|
|
|
}
|
2018-04-27 02:20:56 -04:00
|
|
|
shutdownCh = make(chan struct{})
|
|
|
|
go catchTerminate(shutdownCh)
|
2018-02-05 16:13:06 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func unlockEcho() error {
|
|
|
|
echoLockMutex.Lock()
|
|
|
|
defer echoLockMutex.Unlock()
|
2018-10-16 12:18:29 -04:00
|
|
|
if istty {
|
|
|
|
if origTermStatePtr == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2018-02-05 16:13:06 -05:00
|
|
|
|
2018-10-16 12:18:29 -04:00
|
|
|
fd := int(tty.Fd())
|
2018-02-05 16:13:06 -05:00
|
|
|
|
2018-10-16 12:18:29 -04:00
|
|
|
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, origTermStatePtr); err != nil {
|
|
|
|
return fmt.Errorf("Can't set terminal settings: %v", err)
|
|
|
|
}
|
2018-02-05 16:13:06 -05:00
|
|
|
|
2018-10-16 12:18:29 -04:00
|
|
|
}
|
2018-02-05 16:13:06 -05:00
|
|
|
origTermStatePtr = nil
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// listen exit signals and restore terminal state
|
2018-04-27 02:20:56 -04:00
|
|
|
func catchTerminate(shutdownCh chan struct{}) {
|
2018-02-05 16:13:06 -05:00
|
|
|
sig := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL)
|
|
|
|
defer signal.Stop(sig)
|
|
|
|
select {
|
2018-04-27 02:20:56 -04:00
|
|
|
case <-shutdownCh:
|
2018-02-05 16:13:06 -05:00
|
|
|
unlockEcho()
|
|
|
|
case <-sig:
|
|
|
|
unlockEcho()
|
|
|
|
}
|
|
|
|
}
|