github.com/inspektor-gadget/inspektor-gadget@v0.28.1/cmd/ig/utils/flags.go (about)

     1  // Copyright 2022 The Inspektor Gadget authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package utils
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/containerd/containerd/pkg/cri/constants"
    22  
    23  	commonutils "github.com/inspektor-gadget/inspektor-gadget/cmd/common/utils"
    24  	containerutils "github.com/inspektor-gadget/inspektor-gadget/pkg/container-utils"
    25  	containerutilsTypes "github.com/inspektor-gadget/inspektor-gadget/pkg/container-utils/types"
    26  	"github.com/inspektor-gadget/inspektor-gadget/pkg/types"
    27  
    28  	log "github.com/sirupsen/logrus"
    29  	"github.com/spf13/cobra"
    30  )
    31  
    32  // CommonFlags contains CLI flags common to several gadgets.
    33  type CommonFlags struct {
    34  	// OutputConfig describes the way output should be printed.
    35  	commonutils.OutputConfig
    36  
    37  	// Saves all runtime socket paths
    38  	commonutils.RuntimesSocketPathConfig
    39  
    40  	// Containername allows to filter containers by name.
    41  	Containername string
    42  
    43  	// The name of the container runtimes to be used separated by comma.
    44  	Runtimes string
    45  
    46  	// Host, when set to true, specifies to include all events both from
    47  	// the host and from containers.
    48  	Host bool
    49  
    50  	// RuntimeConfigs contains the list of the container runtimes to be used
    51  	// with their specific socket path.
    52  	RuntimeConfigs []*containerutilsTypes.RuntimeConfig
    53  
    54  	// Number of seconds that the gadget will run for
    55  	Timeout int
    56  
    57  	// ContainerdNamespace is the namespace used by containerd
    58  	ContainerdNamespace string
    59  
    60  	// RuntimeProtocol specifies whether to use the CRI API to talk to the runtime.
    61  	// Useful for docker and containerd.
    62  	// CRI-O is always using the CRI API. Podman is always using the internal API.
    63  	// Supported values: internal, cri.
    64  	RuntimeProtocol string
    65  }
    66  
    67  func AddCommonFlags(command *cobra.Command, commonFlags *CommonFlags) {
    68  	command.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
    69  		// Runtimes Configuration
    70  		switch commonFlags.RuntimeProtocol {
    71  		case containerutilsTypes.RuntimeProtocolInternal:
    72  		case containerutilsTypes.RuntimeProtocolCRI:
    73  		default:
    74  			return commonutils.WrapInErrInvalidArg("--runtime-protocol",
    75  				fmt.Errorf("runtime protocol %q is not supported", commonFlags.RuntimeProtocol))
    76  		}
    77  
    78  		parts := strings.Split(commonFlags.Runtimes, ",")
    79  
    80  	partsLoop:
    81  		for _, p := range parts {
    82  			runtimeName := types.String2RuntimeName(strings.TrimSpace(p))
    83  			socketPath := ""
    84  			namespace := ""
    85  
    86  			switch runtimeName {
    87  			case types.RuntimeNameDocker:
    88  				socketPath = commonFlags.RuntimesSocketPathConfig.Docker
    89  			case types.RuntimeNameContainerd:
    90  				socketPath = commonFlags.RuntimesSocketPathConfig.Containerd
    91  				namespace = commonFlags.ContainerdNamespace
    92  			case types.RuntimeNameCrio:
    93  				socketPath = commonFlags.RuntimesSocketPathConfig.Crio
    94  			case types.RuntimeNamePodman:
    95  				socketPath = commonFlags.RuntimesSocketPathConfig.Podman
    96  			default:
    97  				return commonutils.WrapInErrInvalidArg("--runtime / -r",
    98  					fmt.Errorf("runtime %q is not supported", p))
    99  			}
   100  
   101  			for _, r := range commonFlags.RuntimeConfigs {
   102  				if r.Name == runtimeName {
   103  					log.Infof("Ignoring duplicated runtime %q from %q",
   104  						runtimeName, commonFlags.Runtimes)
   105  					continue partsLoop
   106  				}
   107  			}
   108  
   109  			r := &containerutilsTypes.RuntimeConfig{
   110  				Name:            runtimeName,
   111  				SocketPath:      socketPath,
   112  				RuntimeProtocol: commonFlags.RuntimeProtocol,
   113  				Extra: containerutilsTypes.ExtraConfig{
   114  					Namespace: namespace,
   115  				},
   116  			}
   117  
   118  			commonFlags.RuntimeConfigs = append(commonFlags.RuntimeConfigs, r)
   119  		}
   120  
   121  		// Output Mode
   122  		if err := commonFlags.ParseOutputConfig(); err != nil {
   123  			return err
   124  		}
   125  
   126  		return nil
   127  	}
   128  
   129  	// do not print usage when there is an error
   130  	command.SilenceUsage = true
   131  
   132  	commonutils.AddOutputFlags(command, &commonFlags.OutputConfig)
   133  	commonutils.AddRuntimesSocketPathFlags(command, &commonFlags.RuntimesSocketPathConfig)
   134  
   135  	command.PersistentFlags().StringVarP(
   136  		&commonFlags.Containername,
   137  		"containername",
   138  		"c",
   139  		"",
   140  		"Show only data from containers with that name",
   141  	)
   142  	command.PersistentFlags().BoolVarP(
   143  		&commonFlags.Host,
   144  		"host",
   145  		"",
   146  		false,
   147  		"Show data from both the host and containers",
   148  	)
   149  
   150  	command.PersistentFlags().StringVarP(
   151  		&commonFlags.Runtimes,
   152  		"runtimes", "r",
   153  		strings.Join(containerutils.AvailableRuntimes, ","),
   154  		fmt.Sprintf("Container runtimes to be used separated by comma. Supported values are: %s",
   155  			strings.Join(containerutils.AvailableRuntimes, ", ")),
   156  	)
   157  
   158  	command.PersistentFlags().IntVar(
   159  		&commonFlags.Timeout,
   160  		"timeout",
   161  		0,
   162  		"Number of seconds that the gadget will run for",
   163  	)
   164  
   165  	command.PersistentFlags().StringVar(
   166  		&commonFlags.ContainerdNamespace,
   167  		"containerd-namespace",
   168  		constants.K8sContainerdNamespace,
   169  		"Namespace used by containerd",
   170  	)
   171  
   172  	command.PersistentFlags().StringVar(
   173  		&commonFlags.RuntimeProtocol,
   174  		"runtime-protocol",
   175  		containerutilsTypes.RuntimeProtocolInternal,
   176  		fmt.Sprintf("Container runtime protocol (docker and containerd). Supported values are: %s",
   177  			strings.Join(containerutils.AvailableRuntimeProtocols, ", ")),
   178  	)
   179  }
   180  
   181  func HideFlagTimeout(command *cobra.Command) {
   182  	command.PersistentFlags().MarkHidden("timeout")
   183  }