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
}