mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add runsc usage to list of commands
Also make `runsc debug` write to stdout and log file to make it easier to see the output when running the command manually. PiperOrigin-RevId: 470042053
This commit is contained in:
committed by
gVisor bot
parent
dc3a84baa5
commit
df5374fcfa
@@ -94,6 +94,7 @@ func Main(version string) {
|
||||
subcommands.Register(new(cmd.Debug), debugGroup)
|
||||
subcommands.Register(new(cmd.Statefile), debugGroup)
|
||||
subcommands.Register(new(cmd.Symbolize), debugGroup)
|
||||
subcommands.Register(new(cmd.Usage), debugGroup)
|
||||
|
||||
// Internal commands.
|
||||
const internalGroup = "internal use only"
|
||||
|
||||
+21
-20
@@ -140,23 +140,23 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
if !c.IsSandboxRunning() {
|
||||
return util.Errorf("container sandbox is not running")
|
||||
}
|
||||
log.Infof("Found sandbox %q, PID: %d", c.Sandbox.ID, c.Sandbox.Getpid())
|
||||
util.Infof("Found sandbox %q, PID: %d", c.Sandbox.ID, c.Sandbox.Getpid())
|
||||
|
||||
// Perform synchronous actions.
|
||||
if d.signal > 0 {
|
||||
pid := c.Sandbox.Getpid()
|
||||
log.Infof("Sending signal %d to process: %d", d.signal, pid)
|
||||
util.Infof("Sending signal %d to process: %d", d.signal, pid)
|
||||
if err := unix.Kill(pid, unix.Signal(d.signal)); err != nil {
|
||||
return util.Errorf("failed to send signal %d to processs %d", d.signal, pid)
|
||||
}
|
||||
}
|
||||
if d.stacks {
|
||||
log.Infof("Retrieving sandbox stacks")
|
||||
util.Infof("Retrieving sandbox stacks")
|
||||
stacks, err := c.Sandbox.Stacks()
|
||||
if err != nil {
|
||||
return util.Errorf("retrieving stacks: %v", err)
|
||||
}
|
||||
log.Infof(" *** Stack dump ***\n%s", stacks)
|
||||
util.Infof(" *** Stack dump ***\n%s", stacks)
|
||||
}
|
||||
if d.strace != "" || len(d.logLevel) != 0 || len(d.logPackets) != 0 {
|
||||
args := control.LoggingArgs{}
|
||||
@@ -165,16 +165,16 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
// strace not set, nothing to do here.
|
||||
|
||||
case "off":
|
||||
log.Infof("Disabling strace")
|
||||
util.Infof("Disabling strace")
|
||||
args.SetStrace = true
|
||||
|
||||
case "all":
|
||||
log.Infof("Enabling all straces")
|
||||
util.Infof("Enabling all straces")
|
||||
args.SetStrace = true
|
||||
args.EnableStrace = true
|
||||
|
||||
default:
|
||||
log.Infof("Enabling strace for syscalls: %s", d.strace)
|
||||
util.Infof("Enabling strace for syscalls: %s", d.strace)
|
||||
args.SetStrace = true
|
||||
args.EnableStrace = true
|
||||
args.StraceAllowlist = strings.Split(d.strace, ",")
|
||||
@@ -192,7 +192,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
default:
|
||||
return util.Errorf("invalid log level %q", d.logLevel)
|
||||
}
|
||||
log.Infof("Setting log level %v", args.Level)
|
||||
util.Infof("Setting log level %v", args.Level)
|
||||
}
|
||||
|
||||
if len(d.logPackets) != 0 {
|
||||
@@ -203,18 +203,19 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
}
|
||||
args.LogPackets = lp
|
||||
if args.LogPackets {
|
||||
log.Infof("Enabling packet logging")
|
||||
util.Infof("Enabling packet logging")
|
||||
} else {
|
||||
log.Infof("Disabling packet logging")
|
||||
util.Infof("Disabling packet logging")
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.Sandbox.ChangeLogging(args); err != nil {
|
||||
return util.Errorf(err.Error())
|
||||
}
|
||||
log.Infof("Logging options changed")
|
||||
util.Infof("Logging options changed")
|
||||
}
|
||||
if d.ps {
|
||||
util.Infof("Retrieving process list")
|
||||
pList, err := c.Processes()
|
||||
if err != nil {
|
||||
util.Fatalf("getting processes for container: %v", err)
|
||||
@@ -223,7 +224,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
if err != nil {
|
||||
util.Fatalf("generating JSON: %v", err)
|
||||
}
|
||||
log.Infof(o)
|
||||
util.Infof("%s", o)
|
||||
}
|
||||
|
||||
// Open profiling files.
|
||||
@@ -333,13 +334,13 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
case <-readyChan:
|
||||
break // Safe to proceed.
|
||||
case <-signals:
|
||||
log.Infof("caught signal, waiting at most one more second.")
|
||||
util.Infof("caught signal, waiting at most one more second.")
|
||||
select {
|
||||
case <-signals:
|
||||
log.Infof("caught second signal, exiting immediately.")
|
||||
util.Infof("caught second signal, exiting immediately.")
|
||||
os.Exit(1) // Not finished.
|
||||
case <-time.After(time.Second):
|
||||
log.Infof("timeout, exiting.")
|
||||
util.Infof("timeout, exiting.")
|
||||
os.Exit(1) // Not finished.
|
||||
case <-readyChan:
|
||||
break // Safe to proceed.
|
||||
@@ -350,27 +351,27 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
errorCount := 0
|
||||
if blockErr != nil {
|
||||
errorCount++
|
||||
log.Infof("error collecting block profile: %v", blockErr)
|
||||
util.Infof("error collecting block profile: %v", blockErr)
|
||||
os.Remove(blockFile.Name())
|
||||
}
|
||||
if cpuErr != nil {
|
||||
errorCount++
|
||||
log.Infof("error collecting cpu profile: %v", cpuErr)
|
||||
util.Infof("error collecting cpu profile: %v", cpuErr)
|
||||
os.Remove(cpuFile.Name())
|
||||
}
|
||||
if heapErr != nil {
|
||||
errorCount++
|
||||
log.Infof("error collecting heap profile: %v", heapErr)
|
||||
util.Infof("error collecting heap profile: %v", heapErr)
|
||||
os.Remove(heapFile.Name())
|
||||
}
|
||||
if mutexErr != nil {
|
||||
errorCount++
|
||||
log.Infof("error collecting mutex profile: %v", mutexErr)
|
||||
util.Infof("error collecting mutex profile: %v", mutexErr)
|
||||
os.Remove(mutexFile.Name())
|
||||
}
|
||||
if traceErr != nil {
|
||||
errorCount++
|
||||
log.Infof("error collecting trace profile: %v", traceErr)
|
||||
util.Infof("error collecting trace profile: %v", traceErr)
|
||||
os.Remove(traceFile.Name())
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ func (evs *Events) SetFlags(f *flag.FlagSet) {
|
||||
}
|
||||
|
||||
// Execute implements subcommands.Command.Execute.
|
||||
func (evs *Events) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
|
||||
func (evs *Events) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
|
||||
if f.NArg() != 1 {
|
||||
f.Usage()
|
||||
return subcommands.ExitUsageError
|
||||
|
||||
+13
-13
@@ -17,8 +17,6 @@ package cmd
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
"gvisor.dev/gvisor/runsc/cmd/util"
|
||||
@@ -69,16 +67,8 @@ func (u *Usage) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
util.Fatalf("loading container: %v", err)
|
||||
}
|
||||
|
||||
if !u.fd {
|
||||
m, err := cont.Usage(u.full)
|
||||
if err != nil {
|
||||
util.Fatalf("usage failed: %v", err)
|
||||
}
|
||||
if err := json.NewEncoder(os.Stdout).Encode(m); err != nil {
|
||||
util.Fatalf("Encode MemoryUsage failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
m, err := cont.UsageFD()
|
||||
if u.fd {
|
||||
m, err := cont.Sandbox.UsageFD()
|
||||
if err != nil {
|
||||
util.Fatalf("usagefd failed: %v", err)
|
||||
}
|
||||
@@ -88,7 +78,17 @@ func (u *Usage) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
|
||||
util.Fatalf("Fetch memory usage failed: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Mapped %v, Unknown %v, Total %v\n", mapped, unknown, total)
|
||||
util.Infof("Mapped %v, Unknown %v, Total %v\n", mapped, unknown, total)
|
||||
} else {
|
||||
m, err := cont.Sandbox.Usage(u.full)
|
||||
if err != nil {
|
||||
util.Fatalf("usage failed: %v", err)
|
||||
}
|
||||
encoder := json.NewEncoder(&util.Writer{})
|
||||
encoder.SetIndent("", " ")
|
||||
if err := encoder.Encode(m); err != nil {
|
||||
util.Fatalf("Encode MemoryUsage failed: %v", err)
|
||||
}
|
||||
}
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
@@ -37,6 +37,21 @@ type jsonError struct {
|
||||
Time time.Time `json:"time"`
|
||||
}
|
||||
|
||||
// Writer writes to log and stdout.
|
||||
type Writer struct{}
|
||||
|
||||
// Write implements io.Writer.
|
||||
func (i *Writer) Write(data []byte) (n int, err error) {
|
||||
log.Infof("%s", data)
|
||||
return os.Stdout.Write(data)
|
||||
}
|
||||
|
||||
// Infof writes message to log and stdout.
|
||||
func Infof(format string, args ...interface{}) {
|
||||
log.Infof(format, args)
|
||||
fmt.Printf(format+"\n", args)
|
||||
}
|
||||
|
||||
// Errorf logs error to containerd log (--log), to stderr, and debug logs. It
|
||||
// returns subcommands.ExitFailure for convenience with subcommand.Execute()
|
||||
// methods:
|
||||
|
||||
@@ -678,24 +678,6 @@ func (c *Container) Cat(files []string, out *os.File) error {
|
||||
return c.Sandbox.Cat(c.ID, files, out)
|
||||
}
|
||||
|
||||
// Usage displays memory used by the application.
|
||||
func (c *Container) Usage(full bool) (control.MemoryUsage, error) {
|
||||
log.Debugf("Usage in container, cid: %s, full: %v", c.ID, full)
|
||||
return c.Sandbox.Usage(c.ID, full)
|
||||
}
|
||||
|
||||
// UsageFD shows application memory usage using two donated FDs.
|
||||
func (c *Container) UsageFD() (*control.MemoryUsageRecord, error) {
|
||||
log.Debugf("UsageFD in container, cid: %s", c.ID)
|
||||
return c.Sandbox.UsageFD(c.ID)
|
||||
}
|
||||
|
||||
// Reduce requests that the sentry attempt to reduce its memory usage.
|
||||
func (c *Container) Reduce(wait bool) error {
|
||||
log.Debugf("Reduce in container, cid: %s", c.ID)
|
||||
return c.Sandbox.Reduce(c.ID, wait)
|
||||
}
|
||||
|
||||
// Stream dumps all events to out.
|
||||
func (c *Container) Stream(filters []string, out *os.File) error {
|
||||
log.Debugf("Stream in container, cid: %s", c.ID)
|
||||
|
||||
@@ -2590,7 +2590,7 @@ func TestUsage(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, full := range []bool{false, true} {
|
||||
m, err := cont.Usage(full)
|
||||
m, err := cont.Sandbox.Usage(full)
|
||||
if err != nil {
|
||||
t.Fatalf("error usage from container: %v", err)
|
||||
}
|
||||
@@ -2637,7 +2637,7 @@ func TestUsageFD(t *testing.T) {
|
||||
t.Fatalf("starting container: %v", err)
|
||||
}
|
||||
|
||||
m, err := cont.UsageFD()
|
||||
m, err := cont.Sandbox.UsageFD()
|
||||
if err != nil {
|
||||
t.Fatalf("error usageFD from container: %v", err)
|
||||
}
|
||||
@@ -2683,7 +2683,7 @@ func TestReduce(t *testing.T) {
|
||||
t.Fatalf("starting container: %v", err)
|
||||
}
|
||||
|
||||
if err := cont.Reduce(false); err != nil {
|
||||
if err := cont.Sandbox.Reduce(false); err != nil {
|
||||
t.Fatalf("error reduce from container: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1140,7 +1140,7 @@ func (s *Sandbox) Cat(cid string, files []string, out *os.File) error {
|
||||
}
|
||||
|
||||
// Usage sends the collect call for a container in the sandbox.
|
||||
func (s *Sandbox) Usage(cid string, Full bool) (control.MemoryUsage, error) {
|
||||
func (s *Sandbox) Usage(Full bool) (control.MemoryUsage, error) {
|
||||
log.Debugf("Usage sandbox %q", s.ID)
|
||||
conn, err := s.sandboxConnect()
|
||||
if err != nil {
|
||||
@@ -1156,7 +1156,7 @@ func (s *Sandbox) Usage(cid string, Full bool) (control.MemoryUsage, error) {
|
||||
}
|
||||
|
||||
// UsageFD sends the usagefd call for a container in the sandbox.
|
||||
func (s *Sandbox) UsageFD(cid string) (*control.MemoryUsageRecord, error) {
|
||||
func (s *Sandbox) UsageFD() (*control.MemoryUsageRecord, error) {
|
||||
log.Debugf("Usage sandbox %q", s.ID)
|
||||
conn, err := s.sandboxConnect()
|
||||
if err != nil {
|
||||
@@ -1179,7 +1179,7 @@ func (s *Sandbox) UsageFD(cid string) (*control.MemoryUsageRecord, error) {
|
||||
}
|
||||
|
||||
// Reduce sends the reduce call for a container in the sandbox.
|
||||
func (s *Sandbox) Reduce(cid string, wait bool) error {
|
||||
func (s *Sandbox) Reduce(wait bool) error {
|
||||
log.Debugf("Reduce sandbox %q", s.ID)
|
||||
conn, err := s.sandboxConnect()
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -287,7 +287,7 @@ func runRunsc(tc gtest.TestCase, spec *specs.Spec) error {
|
||||
log.Warningf("%s: Got signal: %v", name, s)
|
||||
done := make(chan bool, 1)
|
||||
dArgs := append([]string{}, args...)
|
||||
dArgs = append(dArgs, "-alsologtostderr=true", "debug", "--stacks", id)
|
||||
dArgs = append(dArgs, "debug", "--stacks", id)
|
||||
go func(dArgs []string) {
|
||||
debug := exec.Command(specutils.ExePath, dArgs...)
|
||||
debug.Stdout = os.Stdout
|
||||
|
||||
Reference in New Issue
Block a user