146 lines
3.2 KiB
Go
146 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/genuinetools/amicontained/container"
|
|
"github.com/genuinetools/amicontained/version"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const (
|
|
// BANNER is what is printed for help/info output
|
|
BANNER = ` _ _ _ _
|
|
__ _ _ __ ___ (_) ___ ___ _ __ | |_ __ _(_)_ __ ___ __| |
|
|
/ _` + "`" + ` | '_ ` + "`" + ` _ \| |/ __/ _ \| '_ \| __/ _` + "`" + ` | | '_ \ / _ \/ _` + "`" + ` |
|
|
| (_| | | | | | | | (_| (_) | | | | || (_| | | | | | __/ (_| |
|
|
\__,_|_| |_| |_|_|\___\___/|_| |_|\__\__,_|_|_| |_|\___|\__,_|
|
|
Container introspection tool.
|
|
Version: %s
|
|
|
|
`
|
|
)
|
|
|
|
var (
|
|
debug bool
|
|
vrsn bool
|
|
)
|
|
|
|
func init() {
|
|
// parse flags
|
|
flag.BoolVar(&vrsn, "version", false, "print version and exit")
|
|
flag.BoolVar(&vrsn, "v", false, "print version and exit (shorthand)")
|
|
flag.BoolVar(&debug, "d", false, "run in debug mode")
|
|
|
|
flag.Usage = func() {
|
|
fmt.Fprint(os.Stderr, fmt.Sprintf(BANNER, version.VERSION))
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
flag.Parse()
|
|
|
|
// set log level
|
|
if debug {
|
|
logrus.SetLevel(logrus.DebugLevel)
|
|
}
|
|
|
|
if vrsn {
|
|
fmt.Printf("amicontained version %s, build %s\n", version.VERSION, version.GITCOMMIT)
|
|
os.Exit(0)
|
|
}
|
|
|
|
if flag.NArg() < 1 {
|
|
return
|
|
}
|
|
|
|
// parse the arg
|
|
arg := flag.Args()[0]
|
|
|
|
if arg == "help" {
|
|
usageAndExit("", 0)
|
|
}
|
|
|
|
if arg == "version" {
|
|
fmt.Printf("amicontained version %s, build %s\n", version.VERSION, version.GITCOMMIT)
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
// Container Runtime
|
|
runtime, err := container.DetectRuntime()
|
|
if err != nil && err != container.ErrContainerRuntimeNotFound {
|
|
log.Fatal(err)
|
|
return
|
|
}
|
|
fmt.Printf("Container Runtime: %s\n", runtime)
|
|
|
|
// Namespaces
|
|
namespaces := []string{"pid"}
|
|
fmt.Println("Has Namespaces:")
|
|
for _, namespace := range namespaces {
|
|
ns, err := container.HasNamespace(namespace)
|
|
if err != nil {
|
|
fmt.Printf("\t%s: error -> %v\n", namespace, err)
|
|
continue
|
|
}
|
|
fmt.Printf("\t%s: %t\n", namespace, ns)
|
|
}
|
|
|
|
// User Namespaces
|
|
userNS, userMappings := container.UserNamespace()
|
|
fmt.Printf("\tuser: %t\n", userNS)
|
|
if len(userMappings) > 0 {
|
|
fmt.Println("User Namespace Mappings:")
|
|
for _, userMapping := range userMappings {
|
|
fmt.Printf("\tContainer -> %d\tHost -> %d\tRange -> %d\n", userMapping.ContainerID, userMapping.HostID, userMapping.Range)
|
|
}
|
|
}
|
|
|
|
// AppArmor Profile
|
|
aaprof := container.AppArmorProfile()
|
|
fmt.Printf("AppArmor Profile: %s\n", aaprof)
|
|
|
|
// Capabilities
|
|
caps, err := container.Capabilities()
|
|
if err != nil {
|
|
logrus.Warnf("getting capabilities failed: %v", err)
|
|
}
|
|
if len(caps) > 0 {
|
|
fmt.Println("Capabilities:")
|
|
for k, v := range caps {
|
|
if len(v) > 0 {
|
|
fmt.Printf("\t%s -> %s\n", k, strings.Join(v, " "))
|
|
}
|
|
}
|
|
}
|
|
|
|
// Chroot
|
|
chroot, err := container.Chroot()
|
|
if err != nil {
|
|
logrus.Debugf("chroot check error: %v", err)
|
|
}
|
|
fmt.Printf("Chroot (not pivot_root): %t\n", chroot)
|
|
|
|
// Seccomp
|
|
seccompMode, err := container.SeccompEnforcingMode()
|
|
if err != nil {
|
|
logrus.Debugf("error: %v", err)
|
|
}
|
|
fmt.Printf("Seccomp: %s\n", seccompMode)
|
|
}
|
|
|
|
func usageAndExit(message string, exitCode int) {
|
|
if message != "" {
|
|
fmt.Fprintf(os.Stderr, message)
|
|
fmt.Fprintf(os.Stderr, "\n\n")
|
|
}
|
|
flag.Usage()
|
|
fmt.Fprintf(os.Stderr, "\n")
|
|
os.Exit(exitCode)
|
|
}
|