func newPodmanContainerHandler()

in container/podman/handler.go [75:201]


func newPodmanContainerHandler(
	name string,
	machineInfoFactory info.MachineInfoFactory,
	fsInfo fs.FsInfo,
	storageDriver docker.StorageDriver,
	storageDir string,
	cgroupSubsystems map[string]string,
	inHostNamespace bool,
	metadataEnvAllowList []string,
	metrics container.MetricSet,
	thinPoolName string,
	thinPoolWatcher *devicemapper.ThinPoolWatcher,
	zfsWatcher *zfs.ZfsWatcher,
) (container.ContainerHandler, error) {
	// Create the cgroup paths.
	cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)

	cgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)
	if err != nil {
		return nil, err
	}

	rootFs := "/"
	if !inHostNamespace {
		rootFs = "/rootfs"
		storageDir = path.Join(rootFs, storageDir)
	}

	rootless := path.Base(name) == containerBaseName
	if rootless {
		name, _ = path.Split(name)
	}

	id := dockerutil.ContainerNameToId(name)

	// We assume that if Inspect fails then the container is not known to Podman.
	ctnr, err := InspectContainer(id)
	if err != nil {
		return nil, err
	}

	rwLayerID, err := rwLayerID(storageDriver, storageDir, id)
	if err != nil {
		return nil, err
	}

	rootfsStorageDir, zfsParent, zfsFilesystem, err := determineDeviceStorage(storageDriver, storageDir, rwLayerID)
	if err != nil {
		return nil, err
	}

	otherStorageDir := filepath.Join(storageDir, string(storageDriver)+"-containers", id)

	handler := &podmanContainerHandler{
		machineInfoFactory: machineInfoFactory,
		cgroupPaths:        cgroupPaths,
		storageDriver:      storageDriver,
		fsInfo:             fsInfo,
		rootfsStorageDir:   rootfsStorageDir,
		ipAddress:          ctnr.NetworkSettings.IPAddress,
		envs:               make(map[string]string),
		labels:             ctnr.Config.Labels,
		image:              ctnr.Config.Image,
		networkMode:        ctnr.HostConfig.NetworkMode,
		fsHandler:          common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, otherStorageDir, fsInfo),
		metrics:            metrics,
		thinPoolName:       thinPoolName,
		zfsParent:          zfsParent,
		reference: info.ContainerReference{
			Id:        id,
			Name:      name,
			Aliases:   []string{strings.TrimPrefix(ctnr.Name, "/"), id},
			Namespace: Namespace,
		},
		libcontainerHandler: containerlibcontainer.NewHandler(cgroupManager, rootFs, ctnr.State.Pid, metrics),
	}

	handler.creationTime, err = time.Parse(time.RFC3339, ctnr.Created)
	if err != nil {
		return nil, fmt.Errorf("failed to parse the create timestamp %q for container %q: %v", ctnr.Created, id, err)
	}

	if ctnr.RestartCount > 0 {
		handler.labels["restartcount"] = fmt.Sprint(ctnr.RestartCount)
	}

	// Obtain the IP address for the container.
	// If the NetworkMode starts with 'container:' then we need to use the IP address of the container specified.
	// This happens in cases such as kubernetes where the containers doesn't have an IP address itself and we need to use the pod's address
	networkMode := string(handler.networkMode)
	if handler.ipAddress == "" && strings.HasPrefix(networkMode, "container:") {
		id := strings.TrimPrefix(networkMode, "container:")
		ctnr, err := InspectContainer(id)
		if err != nil {
			return nil, err
		}
		handler.ipAddress = ctnr.NetworkSettings.IPAddress
	}

	if metrics.Has(container.DiskUsageMetrics) {
		handler.fsHandler = &docker.FsHandler{
			FsHandler:       common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, otherStorageDir, fsInfo),
			ThinPoolWatcher: thinPoolWatcher,
			ZfsWatcher:      zfsWatcher,
			DeviceID:        ctnr.GraphDriver.Data["DeviceId"],
			ZfsFilesystem:   zfsFilesystem,
		}
	}

	// Split env vars to get metadata map.
	for _, exposedEnv := range metadataEnvAllowList {
		if exposedEnv == "" {
			continue
		}

		for _, envVar := range ctnr.Config.Env {
			if envVar != "" {
				splits := strings.SplitN(envVar, "=", 2)
				if len(splits) == 2 && strings.HasPrefix(splits[0], exposedEnv) {
					handler.envs[strings.ToLower(splits[0])] = splits[1]
				}
			}
		}
	}

	return handler, nil
}