in cmd/hub/api/logs.go [44:188]
func Logs(selectors []string, exitOnCompletedOperation bool) int {
filters := parseFilters(selectors)
if len(selectors) > 0 && len(filters) == 0 {
msg := fmt.Sprintf("No entities found by %v", selectors)
if config.Force {
config.AggWarnings = false
util.Warn("%s", msg)
} else {
log.Fatalf("%s", msg)
}
}
updates := make(chan WsMessage, 2)
exitCode := make(chan int)
var names sync.Map
key := func(m *WsMessage) string {
return m.Entity + ":" + m.Id
}
reconnects := 0
var connect func()
connect = func() {
onDisconnect := func() {
time.Sleep(1000)
reconnects++
if config.Debug {
log.Printf("Reconnecting (%d)...", reconnects)
}
go connect()
}
ws, err := hubWsSocketIo(
func() {
if config.Verbose && reconnects == 0 {
log.Print("Reading updates from WebSocket...")
}
},
onDisconnect, onDisconnect)
if err != nil {
if reconnects == 0 {
log.Fatalf("Unable to connect Hub WebSocket: %v", err)
} else {
go onDisconnect()
return
}
}
ws.On("change", func(ch *gosocketio.Channel, args []WsMessage) {
m := WsMessage{}
for _, arg := range args {
if arg.Id != "" {
m.Id = arg.Id
}
if arg.Name != "" {
m.Name = arg.Name
}
if arg.Entity != "" {
m.Entity = arg.Entity
m.Action = arg.Action
m.Success = arg.Success
}
if arg.Logs != "" {
m.Logs = arg.Logs
}
if config.Debug {
if !config.Trace && arg.Logs != "" {
arg.Logs = util.TrimColor(util.Wrap(arg.Logs))
}
fmt.Printf("%s\n", aurora.Cyan(fmt.Sprintf("%+v", arg)).Bold().String())
}
}
if m.Id != "" && m.Entity != "" {
k := key(&m)
if m.Name != "" {
names.LoadOrStore(k, m.Name)
} else {
if maybeStr, ok := names.Load(k); ok {
if str, ok := maybeStr.(string); ok {
m.Name = str
}
}
}
}
updates <- m
})
}
connect()
for {
select {
case code := <-exitCode:
return code
case m := <-updates:
if len(filters) > 0 && !filterMatch(filters, &m) {
continue
}
if m.Logs != "" {
os.Stdout.Write([]byte(m.Logs))
if strings.HasSuffix(m.Action, "-update") {
continue
}
}
success := aurora.Green("success").String()
if !m.Success {
success = aurora.Red("fail").String()
}
fmt.Printf("%s %s %s [%s] %s %s %s\n",
aurora.Magenta("===>").Bold().String(),
time.Now().Format("15:04:05"),
aurora.Green(m.Name).String(),
m.Id,
m.Entity,
aurora.Cyan(m.Action).String(),
success)
if exitOnCompletedOperation && (util.Contains(opCompletedActions, m.Action) ||
(m.Entity == "application" && m.Action == "update")) {
exit := true
success := m.Success
if len(filters) > 0 {
markCompletedFilters(filters, &m)
exit, success = allFiltersCompleted(filters)
}
if exit {
if config.Debug {
log.Print("Logs completed, exiting")
}
code := 0
if !success {
code = 2
}
// wait for updates and logs to catch-up
go func() {
time.Sleep(1 * time.Second)
exitCode <- code
}()
}
}
}
}
}