github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/runtime/local/local.go (about) 1 // Copyright 2022-2024 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 local 16 17 import ( 18 "errors" 19 "fmt" 20 "os" 21 "path/filepath" 22 23 "github.com/cilium/ebpf" 24 25 gadgetregistry "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-registry" 26 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets" 27 "github.com/inspektor-gadget/inspektor-gadget/pkg/operators" 28 "github.com/inspektor-gadget/inspektor-gadget/pkg/params" 29 "github.com/inspektor-gadget/inspektor-gadget/pkg/runtime" 30 "github.com/inspektor-gadget/inspektor-gadget/pkg/utils/host" 31 ) 32 33 type Runtime struct { 34 catalog *runtime.Catalog 35 } 36 37 func New() *Runtime { 38 return &Runtime{ 39 catalog: prepareCatalog(), 40 } 41 } 42 43 func prepareCatalog() *runtime.Catalog { 44 gadgetInfos := make([]*runtime.GadgetInfo, 0) 45 for _, gadgetDesc := range gadgetregistry.GetAll() { 46 gadgetInfos = append(gadgetInfos, runtime.GadgetInfoFromGadgetDesc(gadgetDesc)) 47 } 48 operatorInfos := make([]*runtime.OperatorInfo, 0) 49 for _, operator := range operators.GetAll() { 50 operatorInfos = append(operatorInfos, runtime.OperatorToOperatorInfo(operator)) 51 } 52 return &runtime.Catalog{ 53 Gadgets: gadgetInfos, 54 Operators: operatorInfos, 55 } 56 } 57 58 func (r *Runtime) Init(globalRuntimeParams *params.Params) error { 59 if os.Geteuid() != 0 { 60 return fmt.Errorf("%s must be run as root to be able to run eBPF programs", filepath.Base(os.Args[0])) 61 } 62 63 err := host.Init(host.Config{}) 64 if err != nil { 65 return err 66 } 67 68 return nil 69 } 70 71 func (r *Runtime) Close() error { 72 return nil 73 } 74 75 func (r *Runtime) GlobalParamDescs() params.ParamDescs { 76 return nil 77 } 78 79 func (r *Runtime) ParamDescs() params.ParamDescs { 80 return nil 81 } 82 83 func (r *Runtime) RunBuiltInGadget(gadgetCtx runtime.GadgetContext) (runtime.CombinedGadgetResult, error) { 84 log := gadgetCtx.Logger() 85 86 log.Debugf("running with local runtime") 87 88 gadget, ok := gadgetCtx.GadgetDesc().(gadgets.GadgetInstantiate) 89 if !ok { 90 return nil, errors.New("gadget not instantiable") 91 } 92 93 operatorsParamCollection := gadgetCtx.OperatorsParamCollection() 94 95 // Create gadget instance 96 gadgetInstance, err := gadget.NewInstance() 97 if err != nil { 98 return nil, fmt.Errorf("instantiating gadget: %w", err) 99 } 100 101 // Initialize gadgets, if needed 102 if initClose, ok := gadgetInstance.(gadgets.InitCloseGadget); ok { 103 log.Debugf("calling gadget.Init()") 104 err = initClose.Init(gadgetCtx) 105 if err != nil { 106 return nil, fmt.Errorf("initializing gadget: %w", err) 107 } 108 defer func() { 109 log.Debugf("calling gadget.Close()") 110 initClose.Close() 111 }() 112 } 113 114 // Install operators 115 operatorInstances, err := gadgetCtx.Operators().Instantiate(gadgetCtx, gadgetInstance, operatorsParamCollection) 116 if err != nil { 117 return nil, fmt.Errorf("instantiating operators: %w", err) 118 } 119 log.Debugf("found %d operators: ", len(gadgetCtx.Operators())) 120 for _, operator := range gadgetCtx.Operators() { 121 log.Debugf(" %s", operator.Name()) 122 } 123 124 parser := gadgetCtx.Parser() 125 if parser != nil { 126 // Set event handler 127 if setter, ok := gadgetInstance.(gadgets.EventHandlerSetter); ok { 128 log.Debugf("set event handler") 129 setter.SetEventHandler(parser.EventHandlerFunc(operatorInstances.Enrich)) 130 } 131 132 // Set event handler for array results 133 if setter, ok := gadgetInstance.(gadgets.EventHandlerArraySetter); ok { 134 log.Debugf("set event handler for arrays") 135 setter.SetEventHandlerArray(parser.EventHandlerFuncArray(operatorInstances.Enrich)) 136 } 137 138 // Set event enricher (currently only used by profile/cpu) 139 if setter, ok := gadgetInstance.(gadgets.EventEnricherSetter); ok { 140 log.Debugf("set event enricher") 141 setter.SetEventEnricher(operatorInstances.Enrich) 142 } 143 } 144 145 log.Debug("calling operator.PreGadgetRun()") 146 err = operatorInstances.PreGadgetRun() 147 if err != nil { 148 return nil, fmt.Errorf("gadget prerun: %w", err) 149 } 150 defer func() { 151 log.Debug("calling operator.PostGadgetRun()") 152 operatorInstances.PostGadgetRun() 153 }() 154 155 if run, ok := gadgetInstance.(gadgets.RunGadget); ok { 156 log.Debugf("calling gadget.Run()") 157 err := run.Run(gadgetCtx) 158 if err != nil { 159 var ve *ebpf.VerifierError 160 if errors.As(err, &ve) { 161 gadgetCtx.Logger().Debugf("running gadget: verifier error: %+v\n", ve) 162 } 163 return nil, fmt.Errorf("running gadget: %w", err) 164 } 165 return nil, nil 166 } 167 if runWithResult, ok := gadgetInstance.(gadgets.RunWithResultGadget); ok { 168 log.Debugf("calling gadget.RunWithResult()") 169 out, err := runWithResult.RunWithResult(gadgetCtx) 170 if err != nil { 171 var ve *ebpf.VerifierError 172 if errors.As(err, &ve) { 173 gadgetCtx.Logger().Debugf("running (with result) gadget: verifier error: %+v\n", ve) 174 } 175 return nil, fmt.Errorf("running (with result) gadget: %w", err) 176 } 177 return runtime.CombinedGadgetResult{"": &runtime.GadgetResult{Payload: out}}, nil 178 } 179 return nil, errors.New("gadget not runnable") 180 } 181 182 func (r *Runtime) GetCatalog() (*runtime.Catalog, error) { 183 return r.catalog, nil 184 } 185 186 func (r *Runtime) SetDefaultValue(key params.ValueHint, value string) { 187 panic("not supported, yet") 188 } 189 190 func (r *Runtime) GetDefaultValue(key params.ValueHint) (string, bool) { 191 return "", false 192 }