func (o *TraceRunnerOptions) Complete(cmd *cobra.Command, args []string) error {
	return nil
}
Complete completes the setup of the command.
package cmd
import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"os/signal"
	"path"
	"strconv"
	"strings"
	"syscall"
	"time"
	"github.com/iovisor/kubectl-trace/pkg/downloader"
	"github.com/iovisor/kubectl-trace/pkg/procfs"
	"github.com/iovisor/kubectl-trace/pkg/pty"
	"github.com/iovisor/kubectl-trace/pkg/tracejob"
	"github.com/iovisor/kubectl-trace/pkg/upload"
	"github.com/spf13/cobra"
)
type pidDescriber func(string) (string, error)
type postProcessor func() (string, []string, error)
const (
	MetadataDir = "/tmp/kubectl-trace"
	bpftrace = "bpftrace"
	bcc      = "bcc"
	rbspy    = "rbspy"
	fake     = "fake"
)
var (
	bpfTraceBinaryPath = "/usr/bin/bpftrace"
	bccToolsDir        = "/usr/share/bcc/tools/"
	fakeToolsDir       = "/usr/share/fake/"
)
type outputType string
const (
	stdout   outputType = "stdout"
	download outputType = "download"
	gcs      outputType = "gs"
)
type TraceRunnerOptions struct {
	tracer string
	podUID string
	containerID string
	processSelector string
	output string
	program string
	programArgs []string
	parsedSelector *tracejob.ProcessSelector
	outputType     outputType
}
func NewTraceRunnerOptions() *TraceRunnerOptions {
	return &TraceRunnerOptions{}
}
func NewTraceRunnerCommand() *cobra.Command {
	o := NewTraceRunnerOptions()
	cmd := &cobra.Command{
		PreRunE: func(c *cobra.Command, args []string) error {
			return o.Validate(c, args)
		},
		RunE: func(c *cobra.Command, args []string) error {
			if err := o.Complete(c, args); err != nil {
				return err
			}
			if err := o.Run(); err != nil {
				fmt.Fprintln(os.Stdout, err.Error())
				return err
			}
			return nil
		},
	}
	cmd.Flags().StringVar(&o.tracer, "tracer", "bpftrace", "Tracing system to use")
	cmd.Flags().StringVar(&o.podUID, "pod-uid", "", "UID of target pod")
	cmd.Flags().StringVar(&o.containerID, "container-id", "", "ID of target container")
	cmd.Flags().StringVar(&o.processSelector, "process-selector", "", "Process Selector (similar to a label query) to filter on")
	cmd.Flags().StringVar(&o.output, "output", "stdout", "Where to send tracing output (stdout or local path)")
	cmd.Flags().StringVar(&o.program, "program", "/programs/program.bt", "Tracer input script or executable")
	cmd.Flags().StringArrayVar(&o.programArgs, "args", o.programArgs, "Arguments to pass through to executable in --program")
	return cmd
}
func (o *TraceRunnerOptions) Validate(cmd *cobra.Command, args []string) error {
	switch o.tracer {
	case bpftrace, bcc, rbspy, fake:
	default:
		return fmt.Errorf("unknown tracer %s", o.tracer)
	}
	if len(o.output) == 0 {
		return fmt.Errorf("output cannot be empty when specified")
	}
	switch {
	case o.output == "stdout":
		o.outputType = stdout
	case o.output[0] == '/' || o.output[0] == '.':
		o.outputType = download
	case strings.HasPrefix(o.output, "gs://"):
		o.outputType = gcs
	default:
		return fmt.Errorf("unknown output %s", o.output)
	}
	parsed, err := tracejob.NewProcessSelector(o.processSelector)
	if err != nil {
		return fmt.Errorf(err.Error())
	}
	o.parsedSelector = parsed
	switch o.tracer {
	case bpftrace, bcc:
	case fake:
		if _, ok := o.parsedSelector.Pid(); !ok {
			return fmt.Errorf(pidProcessSelectorRequiredForTracer, fake)
		}
	case rbspy:
		if _, ok := o.parsedSelector.Pid(); !ok {
			return fmt.Errorf(pidProcessSelectorRequiredForTracer, rbspy)
		}
	default:
		panic("We shouldn't get here; have you accounted for all tracer types?")
	}
	return nil
}