127 lines
4.1 KiB
Go
127 lines
4.1 KiB
Go
// Copyright 2018 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/google/subcommands"
|
|
"gvisor.dev/gvisor/runsc/flag"
|
|
)
|
|
|
|
// NewHelp returns a help command for the given commander.
|
|
func NewHelp(cdr *subcommands.Commander) *Help {
|
|
return &Help{
|
|
cdr: cdr,
|
|
}
|
|
}
|
|
|
|
// Help implements subcommands.Command for the "help" command. The 'help'
|
|
// command prints help for commands registered to a Commander but also allows for
|
|
// registering additional help commands that print other documentation.
|
|
type Help struct {
|
|
cdr *subcommands.Commander
|
|
commands []subcommands.Command
|
|
help bool
|
|
}
|
|
|
|
// Name implements subcommands.Command.Name.
|
|
func (*Help) Name() string {
|
|
return "help"
|
|
}
|
|
|
|
// Synopsis implements subcommands.Command.Synopsis.
|
|
func (*Help) Synopsis() string {
|
|
return "Print help documentation."
|
|
}
|
|
|
|
// Usage implements subcommands.Command.Usage.
|
|
func (*Help) Usage() string {
|
|
return `help [<subcommand>]:
|
|
With an argument, prints detailed information on the use of
|
|
the specified topic or subcommand. With no argument, print a list of
|
|
all commands and a brief description of each.
|
|
`
|
|
}
|
|
|
|
// SetFlags implements subcommands.Command.SetFlags.
|
|
func (h *Help) SetFlags(f *flag.FlagSet) {}
|
|
|
|
// Execute implements subcommands.Command.Execute.
|
|
func (h *Help) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
|
|
switch f.NArg() {
|
|
case 0:
|
|
fmt.Fprintf(h.cdr.Output, "Usage: %s <flags> <subcommand> <subcommand args>\n\n", h.cdr.Name())
|
|
fmt.Fprintf(h.cdr.Output, `runsc is a command line client for running applications packaged in the Open
|
|
Container Initiative (OCI) format. Applications run by runsc are run in an
|
|
isolated gVisor sandbox that emulates a Linux environment.
|
|
|
|
gVisor is a user-space kernel, written in Go, that implements a substantial
|
|
portion of the Linux system call interface. It provides an additional layer
|
|
of isolation between running applications and the host operating system.
|
|
|
|
Functionality is provided by subcommands. For additonal help on individual
|
|
subcommands use "%s %s <subcommand>".
|
|
|
|
`, h.cdr.Name(), h.Name())
|
|
h.cdr.VisitGroups(func(g *subcommands.CommandGroup) {
|
|
h.cdr.ExplainGroup(h.cdr.Output, g)
|
|
})
|
|
|
|
fmt.Fprintf(h.cdr.Output, "Additional help topics (Use \"%s %s <topic>\" to see help on the topic):\n", h.cdr.Name(), h.Name())
|
|
for _, cmd := range h.commands {
|
|
fmt.Fprintf(h.cdr.Output, "\t%-15s %s\n", cmd.Name(), cmd.Synopsis())
|
|
}
|
|
fmt.Fprintf(h.cdr.Output, "\nUse \"%s flags\" for a list of top-level flags\n", h.cdr.Name())
|
|
return subcommands.ExitSuccess
|
|
default:
|
|
// Look for commands registered to the commander and print help explanation if found.
|
|
found := false
|
|
h.cdr.VisitCommands(func(g *subcommands.CommandGroup, cmd subcommands.Command) {
|
|
if f.Arg(0) == cmd.Name() {
|
|
h.cdr.ExplainCommand(h.cdr.Output, cmd)
|
|
found = true
|
|
}
|
|
})
|
|
if found {
|
|
return subcommands.ExitSuccess
|
|
}
|
|
|
|
// Next check commands registered to the help command.
|
|
for _, cmd := range h.commands {
|
|
if f.Arg(0) == cmd.Name() {
|
|
fs := flag.NewFlagSet(f.Arg(0), flag.ContinueOnError)
|
|
fs.Usage = func() { h.cdr.ExplainCommand(h.cdr.Error, cmd) }
|
|
cmd.SetFlags(fs)
|
|
if fs.Parse(f.Args()[1:]) != nil {
|
|
return subcommands.ExitUsageError
|
|
}
|
|
return cmd.Execute(ctx, f, args...)
|
|
}
|
|
}
|
|
|
|
fmt.Fprintf(h.cdr.Error, "Subcommand %s not understood\n", f.Arg(0))
|
|
}
|
|
|
|
f.Usage()
|
|
return subcommands.ExitUsageError
|
|
}
|
|
|
|
// Register registers a new help command.
|
|
func (h *Help) Register(cmd subcommands.Command) {
|
|
h.commands = append(h.commands, cmd)
|
|
}
|