Compare commits
1 Commits
v0.14.0
...
v0.3.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b477c261e5 |
@@ -109,6 +109,8 @@ func ValidateHostName(name string) bool {
|
||||
|
||||
func (h *Host) Create(name string) error {
|
||||
// create the instance
|
||||
log.Progress.Start("Creating the instance")
|
||||
defer log.Progress.Stop()
|
||||
if err := h.Driver.Create(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -120,6 +122,7 @@ func (h *Host) Create(name string) error {
|
||||
|
||||
// TODO: Not really a fan of just checking "none" here.
|
||||
if h.Driver.DriverName() != "none" {
|
||||
log.Progress.Start("Waiting for instance to come up")
|
||||
if err := WaitForSSH(h); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -129,6 +132,7 @@ func (h *Host) Create(name string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Progress.Start("Provisioning the instance")
|
||||
if err := provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -252,6 +256,8 @@ func (h *Host) Upgrade() error {
|
||||
}
|
||||
|
||||
func (h *Host) Remove(force bool) error {
|
||||
log.Progress.Start("Removing the instance")
|
||||
defer log.Progress.Stop()
|
||||
if err := h.Driver.Remove(); err != nil {
|
||||
if !force {
|
||||
return err
|
||||
|
||||
@@ -36,7 +36,8 @@ type Logger interface {
|
||||
}
|
||||
|
||||
var (
|
||||
l = TerminalLogger{}
|
||||
l = TerminalLogger{}
|
||||
Progress = NewProgress()
|
||||
)
|
||||
|
||||
// TODO: I think this is superflous and can be replaced by one check for if
|
||||
|
||||
142
log/progress.go
Normal file
142
log/progress.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/term"
|
||||
)
|
||||
|
||||
type Progressor struct {
|
||||
title string
|
||||
stopChan chan bool
|
||||
isActive bool
|
||||
isTerminal bool
|
||||
withColor bool
|
||||
termWidth int
|
||||
clearBuffer []byte
|
||||
}
|
||||
|
||||
func NewProgress() *Progressor {
|
||||
var (
|
||||
isTerminal = false
|
||||
withColor = false
|
||||
termWidth int
|
||||
clearBuffer []byte
|
||||
)
|
||||
fd := os.Stdout.Fd()
|
||||
isTerminal = term.IsTerminal(fd)
|
||||
if isTerminal {
|
||||
winsize, err := term.GetWinsize(fd)
|
||||
if err != nil {
|
||||
termWidth = 80
|
||||
} else {
|
||||
termWidth = int(winsize.Width)
|
||||
}
|
||||
if isColorTerminal() {
|
||||
withColor = true
|
||||
}
|
||||
clearBuffer = make([]byte, termWidth)
|
||||
for i := range clearBuffer {
|
||||
copy(clearBuffer[i:], " ")
|
||||
}
|
||||
copy(clearBuffer[0:], "\r")
|
||||
}
|
||||
return &Progressor{
|
||||
stopChan: make(chan bool, 1),
|
||||
isActive: false,
|
||||
isTerminal: isTerminal,
|
||||
withColor: withColor,
|
||||
termWidth: termWidth,
|
||||
clearBuffer: clearBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
// invoke with: 'log.Progress.Start("some description")'
|
||||
func (p *Progressor) Start(msg string) {
|
||||
if !p.isTerminal || isDebug() {
|
||||
Info(msg)
|
||||
return
|
||||
}
|
||||
// stop current progress
|
||||
if p.isActive {
|
||||
p.Stop()
|
||||
}
|
||||
p.title = msg
|
||||
p.isActive = true
|
||||
go p.writer()
|
||||
}
|
||||
|
||||
// invoke with: 'log.Progress.Stop()'
|
||||
func (p *Progressor) Stop() {
|
||||
if p.isActive {
|
||||
p.stopChan <- true
|
||||
p.isActive = false
|
||||
// variant a - remove progress
|
||||
os.Stdout.Write(p.clearBuffer)
|
||||
os.Stdout.Write([]byte("\r"))
|
||||
os.Stdout.Sync()
|
||||
// variant b - keep progress and prefix with "+"
|
||||
//os.Stdout.Write([]byte("\r+\n"))
|
||||
//os.Stdout.Sync()
|
||||
}
|
||||
}
|
||||
|
||||
// write out progress in a loop
|
||||
func (p *Progressor) writer() {
|
||||
for {
|
||||
select {
|
||||
case <-p.stopChan:
|
||||
return
|
||||
default:
|
||||
var out string
|
||||
charset := []string{"|", "/", "-", "\\"}
|
||||
for i := 0; i < len(charset); i++ {
|
||||
out = charset[i]
|
||||
if p.withColor {
|
||||
out = "\x1b[1;32m" + charset[i] + "\x1b[0m"
|
||||
}
|
||||
os.Stdout.Write([]byte("\r" + out + " " + p.title))
|
||||
os.Stdout.Sync()
|
||||
time.Sleep(time.Millisecond * 150)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isColorTerminal() bool {
|
||||
matches := []string{
|
||||
"Eterm",
|
||||
"ansi",
|
||||
"color",
|
||||
"console",
|
||||
"cygwin",
|
||||
"dtterm",
|
||||
"eterm-color",
|
||||
"gnome",
|
||||
"konsole",
|
||||
"kterm",
|
||||
"linux",
|
||||
"mach-color",
|
||||
"mlterm",
|
||||
"putty",
|
||||
"rxvt",
|
||||
"screen",
|
||||
"vt100",
|
||||
"xterm",
|
||||
}
|
||||
if os.Getenv("COLORTERM") != "" {
|
||||
return true
|
||||
}
|
||||
term := os.Getenv("TERM")
|
||||
if term == "dumb" {
|
||||
return false
|
||||
}
|
||||
for _, name := range matches {
|
||||
if strings.Contains(term, name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -12,12 +12,20 @@ type TerminalLogger struct {
|
||||
}
|
||||
|
||||
func (t TerminalLogger) log(args ...interface{}) {
|
||||
if Progress.isActive {
|
||||
Progress.Stop()
|
||||
defer Progress.Start(Progress.title)
|
||||
}
|
||||
fmt.Print(args...)
|
||||
fmt.Print(t.fieldOut, "\n")
|
||||
t.fieldOut = ""
|
||||
}
|
||||
|
||||
func (t TerminalLogger) logf(fmtString string, args ...interface{}) {
|
||||
if Progress.isActive {
|
||||
Progress.Stop()
|
||||
defer Progress.Start(Progress.title)
|
||||
}
|
||||
fmt.Printf(fmtString, args...)
|
||||
fmt.Print(t.fieldOut, "\n")
|
||||
t.fieldOut = ""
|
||||
|
||||
Reference in New Issue
Block a user