Add Diagnostics (#203)

* Add container suplimentary groups support

* Add diagnostic gathering

* Fix incorrect userid group searching

* one last tiny fix

* one last tiny fix
This commit is contained in:
Rob Parker
2018-09-03 17:08:26 +01:00
committed by GitHub
parent 9a7d44fef6
commit 3989661778
4 changed files with 82 additions and 12 deletions

View File

@@ -21,9 +21,11 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"sync" "sync"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/logger" "github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/internal/mqini" "github.com/ibm-messaging/mq-container/internal/mqini"
) )
@@ -31,6 +33,8 @@ import (
// var debug = false // var debug = false
var log *logger.Logger var log *logger.Logger
var collectDiagOnFail bool = false
func logTerminationf(format string, args ...interface{}) { func logTerminationf(format string, args ...interface{}) {
logTermination(fmt.Sprintf(format, args)) logTermination(fmt.Sprintf(format, args))
} }
@@ -45,6 +49,10 @@ func logTermination(args ...interface{}) {
log.Debug(err) log.Debug(err)
} }
log.Error(msg) log.Error(msg)
if collectDiagOnFail {
logDiagnostics()
}
} }
func getLogFormat() string { func getLogFormat() string {
@@ -111,3 +119,27 @@ func configureLogger(name string) (mirrorFunc, error) {
return nil, fmt.Errorf("invalid value for LOG_FORMAT: %v", f) return nil, fmt.Errorf("invalid value for LOG_FORMAT: %v", f)
} }
} }
func logDiagnostics() {
log.Debug("--- Start Diagnostics ---")
// show the directory ownership/permissions
out, _, _ := command.Run("ls", "-l", "/mnt/")
log.Debugf("/mnt/:\n%s", out)
out, _, _ = command.Run("ls", "-l", "/mnt/mqm")
log.Debugf("/mnt/mqm:\n%s", out)
out, _, _ = command.Run("ls", "-l", "/mnt/mqm/data")
log.Debugf("/mnt/mqm/data:\n%s", out)
out, _, _ = command.Run("ls", "-l", "/var/mqm")
log.Debugf("/var/mqm:\n%s", out)
out, _, _ = command.Run("ls", "-l", "/var/mqm/errors")
log.Debugf("/var/mqm/errors:\n%s", out)
// Print out summary of any FDCs
cmd := exec.Command("/opt/mqm/bin/ffstsummary")
cmd.Dir = "/var/mqm/errors"
outB, _ := cmd.CombinedOutput()
log.Debugf("ffstsummary:\n%s", string(outB))
log.Debug("--- End Diagnostics ---")
}

View File

@@ -58,14 +58,16 @@ func doMain() error {
// Start signal handler // Start signal handler
signalControl := signalHandler(name) signalControl := signalHandler(name)
// Enable diagnostic collecting on failure
collectDiagOnFail = true
err = logConfig() err = verifyCurrentUser()
if err != nil { if err != nil {
logTermination(err) logTermination(err)
return err return err
} }
err = verifyCurrentUser() err = logConfig()
if err != nil { if err != nil {
logTermination(err) logTermination(err)
return err return err

View File

@@ -44,7 +44,6 @@ func waitForFile(ctx context.Context, path string) (os.FileInfo, error) {
return nil, fmt.Errorf("mirror: unable to get info on file %v", path) return nil, fmt.Errorf("mirror: unable to get info on file %v", path)
} }
} }
log.Debugf("File exists: %v, %v", path, fi.Size())
return fi, nil return fi, nil
} }
} }
@@ -121,6 +120,7 @@ func mirrorLog(ctx context.Context, wg *sync.WaitGroup, path string, fromStart b
if fi == nil { if fi == nil {
return return
} }
log.Debugf("File exists: %v, %v", path, fi.Size())
f, err = os.OpenFile(path, os.O_RDONLY, 0) f, err = os.OpenFile(path, os.O_RDONLY, 0)
if err != nil { if err != nil {
log.Error(err) log.Error(err)

View File

@@ -23,7 +23,7 @@ import (
"github.com/ibm-messaging/mq-container/internal/command" "github.com/ibm-messaging/mq-container/internal/command"
) )
const groupName string = "suplgroup" const groupName string = "supplgrp"
func verifyCurrentUser() error { func verifyCurrentUser() error {
log.Debug("Verifying current user information") log.Debug("Verifying current user information")
@@ -36,9 +36,9 @@ func verifyCurrentUser() error {
// Not supported yet // Not supported yet
return fmt.Errorf("Container is running as mqm user which is not supported. Please run this container as root") return fmt.Errorf("Container is running as mqm user which is not supported. Please run this container as root")
} else if curUser.Username == "root" { } else if curUser.Username == "root" {
// We're running as root so need to check for suplimentary groups. // We're running as root so need to check for supplementary groups.
// We can't use the golang User.GroupIDs as it doesn't seem to detect container supplimentary groups.. // We can't use the golang User.GroupIDs as it doesn't seem to detect container supplementary groups..
groups, err := getCurrentGroups() groups, err := getCurrentUserGroups()
for _, e := range groups { for _, e := range groups {
_, _, testGroup := command.Run("getent", "group", e) _, _, testGroup := command.Run("getent", "group", e)
if testGroup != nil { if testGroup != nil {
@@ -64,9 +64,9 @@ func verifyCurrentUser() error {
} }
func logUser() { func logUser() {
u, err := user.Current() u, usererr := user.Current()
if err == nil { if usererr == nil {
g, err := getCurrentGroups() g, err := getCurrentUserGroups()
if err != nil && len(g) == 0 { if err != nil && len(g) == 0 {
log.Printf("Running as user ID %v (%v) with primary group %v", u.Uid, u.Name, u.Gid) log.Printf("Running as user ID %v (%v) with primary group %v", u.Uid, u.Name, u.Gid)
} else { } else {
@@ -77,12 +77,30 @@ func logUser() {
g = append(g[:i], g[i+1:]...) g = append(g[:i], g[i+1:]...)
} }
} }
log.Printf("Running as user ID %v (%v) with primary group %v, and supplemental groups %v", u.Uid, u.Name, u.Gid, strings.Join(g, ",")) log.Printf("Running as user ID %v (%v) with primary group %v, and supplementary groups %v", u.Uid, u.Name, u.Gid, strings.Join(g, ","))
}
}
if usererr == nil && u.Username != "mqm" {
mqm, err := user.Lookup("mqm")
// Need to print out mqm user details as well.
g, err := getUserGroups(mqm)
if err != nil && len(g) == 0 {
log.Printf("MQM user ID %v (%v) has primary group %v", mqm.Uid, "mqm", mqm.Gid)
} else {
// Look for the primary group in the list of group IDs
for i, v := range g {
if v == mqm.Gid {
// Remove the element from the slice
g = append(g[:i], g[i+1:]...)
}
}
log.Printf("MQM user ID %v (%v) has primary group %v, and supplementary groups %v", mqm.Uid, "mqm", mqm.Gid, strings.Join(g, ","))
} }
} }
} }
func getCurrentGroups() ([]string, error) { func getCurrentUserGroups() ([]string, error) {
var nilArray []string var nilArray []string
out, _, err := command.Run("id", "--groups") out, _, err := command.Run("id", "--groups")
if err != nil { if err != nil {
@@ -99,3 +117,21 @@ func getCurrentGroups() ([]string, error) {
groups := strings.Split(out, " ") groups := strings.Split(out, " ")
return groups, nil return groups, nil
} }
func getUserGroups(usr *user.User) ([]string, error) {
var nilArray []string
out, _, err := command.Run("id", "--groups", usr.Uid)
if err != nil {
log.Debugf("Unable to get user %s groups", usr.Uid)
return nilArray, err
}
out = strings.TrimSpace(out)
if out == "" {
// we don't have any groups?
return nilArray, fmt.Errorf("Unable to determine groups for user %s", usr.Uid)
}
groups := strings.Split(out, " ")
return groups, nil
}