github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/ig-manager/ig-manager.go (about)

     1  // Copyright 2019-2021 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 igmanager
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/cilium/ebpf"
    21  	"github.com/cilium/ebpf/rlimit"
    22  	log "github.com/sirupsen/logrus"
    23  
    24  	containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection"
    25  	containerutils "github.com/inspektor-gadget/inspektor-gadget/pkg/container-utils"
    26  	runtimeclient "github.com/inspektor-gadget/inspektor-gadget/pkg/container-utils/runtime-client"
    27  	containerutilsTypes "github.com/inspektor-gadget/inspektor-gadget/pkg/container-utils/types"
    28  	containersmap "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgettracermanager/containers-map"
    29  	tracercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/tracer-collection"
    30  	"github.com/inspektor-gadget/inspektor-gadget/pkg/types"
    31  )
    32  
    33  type IGManager struct {
    34  	containercollection.ContainerCollection
    35  
    36  	tracerCollection *tracercollection.TracerCollection
    37  
    38  	// containersMap is the global map at /sys/fs/bpf/gadget/containers
    39  	// exposing container details for each mount namespace.
    40  	containersMap *containersmap.ContainersMap
    41  }
    42  
    43  func (l *IGManager) ContainersMap() *ebpf.Map {
    44  	if l.containersMap == nil {
    45  		return nil
    46  	}
    47  
    48  	return l.containersMap.ContainersMap()
    49  }
    50  
    51  func (l *IGManager) Dump() string {
    52  	out := "List of containers:\n"
    53  	l.ContainerCollection.ContainerRange(func(c *containercollection.Container) {
    54  		out += fmt.Sprintf("%+v\n", c)
    55  	})
    56  	return out
    57  }
    58  
    59  func (l *IGManager) CreateMountNsMap(id string, containerSelector containercollection.ContainerSelector) (*ebpf.Map, error) {
    60  	if err := l.tracerCollection.AddTracer(id, containerSelector); err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	mountnsmap, err := l.tracerCollection.TracerMountNsMap(id)
    65  	if err != nil {
    66  		l.tracerCollection.RemoveTracer(id)
    67  		return nil, err
    68  	}
    69  
    70  	return mountnsmap, nil
    71  }
    72  
    73  func (l *IGManager) RemoveMountNsMap(id string) error {
    74  	return l.tracerCollection.RemoveTracer(id)
    75  }
    76  
    77  func NewManager(runtimes []*containerutilsTypes.RuntimeConfig) (*IGManager, error) {
    78  	l := &IGManager{}
    79  
    80  	var err error
    81  	l.tracerCollection, err = tracercollection.NewTracerCollection(&l.ContainerCollection)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  
    86  	if err := rlimit.RemoveMemlock(); err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	l.containersMap, err = containersmap.NewContainersMap("")
    91  	if err != nil {
    92  		return nil, fmt.Errorf("creating containers map: %w", err)
    93  	}
    94  
    95  	opts := []containercollection.ContainerCollectionOption{
    96  		containercollection.WithPubSub(l.containersMap.ContainersMapUpdater()),
    97  		containercollection.WithOCIConfigEnrichment(),
    98  		containercollection.WithCgroupEnrichment(),
    99  		containercollection.WithLinuxNamespaceEnrichment(),
   100  		containercollection.WithMultipleContainerRuntimesEnrichment(runtimes),
   101  		containercollection.WithContainerFanotifyEbpf(),
   102  		containercollection.WithTracerCollection(l.tracerCollection),
   103  	}
   104  
   105  	if !log.IsLevelEnabled(log.DebugLevel) && isDefaultContainerRuntimeConfig(runtimes) {
   106  		warnings := []containercollection.ContainerCollectionOption{containercollection.WithDisableContainerRuntimeWarnings()}
   107  		opts = append(warnings, opts...)
   108  	}
   109  
   110  	err = l.ContainerCollection.Initialize(opts...)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	return l, nil
   116  }
   117  
   118  func (l *IGManager) Close() {
   119  	l.ContainerCollection.Close()
   120  	if l.tracerCollection != nil {
   121  		l.tracerCollection.Close()
   122  	}
   123  	if l.containersMap != nil {
   124  		l.containersMap.Close()
   125  	}
   126  }
   127  
   128  func isDefaultContainerRuntimeConfig(runtimes []*containerutilsTypes.RuntimeConfig) bool {
   129  	if len(runtimes) != len(containerutils.AvailableRuntimes) {
   130  		return false
   131  	}
   132  
   133  	var customSocketPath bool
   134  	for _, runtime := range runtimes {
   135  		switch runtime.Name {
   136  		case types.RuntimeNameDocker:
   137  			customSocketPath = runtime.SocketPath != runtimeclient.DockerDefaultSocketPath
   138  		case types.RuntimeNameContainerd:
   139  			customSocketPath = runtime.SocketPath != runtimeclient.ContainerdDefaultSocketPath
   140  		case types.RuntimeNameCrio:
   141  			customSocketPath = runtime.SocketPath != runtimeclient.CrioDefaultSocketPath
   142  		case types.RuntimeNamePodman:
   143  			customSocketPath = runtime.SocketPath != runtimeclient.PodmanDefaultSocketPath
   144  		default:
   145  			customSocketPath = true
   146  		}
   147  		if customSocketPath {
   148  			return false
   149  		}
   150  	}
   151  
   152  	return true
   153  }