github.com/google/cadvisor@v0.49.1/container/docker/utils/docker.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     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  	"os"
    20  	"path"
    21  	"regexp"
    22  	"strings"
    23  
    24  	dockertypes "github.com/docker/docker/api/types"
    25  	v1 "github.com/google/cadvisor/info/v1"
    26  )
    27  
    28  const (
    29  	DriverStatusPoolName      = "Pool Name"
    30  	DriverStatusMetadataFile  = "Metadata file"
    31  	DriverStatusParentDataset = "Parent Dataset"
    32  )
    33  
    34  // Regexp that identifies docker cgroups, containers started with
    35  // --cgroup-parent have another prefix than 'docker'
    36  var cgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)
    37  
    38  func DriverStatusValue(status [][2]string, target string) string {
    39  	for _, v := range status {
    40  		if strings.EqualFold(v[0], target) {
    41  			return v[1]
    42  		}
    43  	}
    44  
    45  	return ""
    46  }
    47  
    48  func DockerThinPoolName(info dockertypes.Info) (string, error) {
    49  	poolName := DriverStatusValue(info.DriverStatus, DriverStatusPoolName)
    50  	if len(poolName) == 0 {
    51  		return "", fmt.Errorf("Could not get devicemapper pool name")
    52  	}
    53  
    54  	return poolName, nil
    55  }
    56  
    57  func DockerMetadataDevice(info dockertypes.Info) (string, error) {
    58  	metadataDevice := DriverStatusValue(info.DriverStatus, DriverStatusMetadataFile)
    59  	if len(metadataDevice) != 0 {
    60  		return metadataDevice, nil
    61  	}
    62  
    63  	poolName, err := DockerThinPoolName(info)
    64  	if err != nil {
    65  		return "", err
    66  	}
    67  
    68  	metadataDevice = fmt.Sprintf("/dev/mapper/%s_tmeta", poolName)
    69  
    70  	if _, err := os.Stat(metadataDevice); err != nil {
    71  		return "", err
    72  	}
    73  
    74  	return metadataDevice, nil
    75  }
    76  
    77  func DockerZfsFilesystem(info dockertypes.Info) (string, error) {
    78  	filesystem := DriverStatusValue(info.DriverStatus, DriverStatusParentDataset)
    79  	if len(filesystem) == 0 {
    80  		return "", fmt.Errorf("Could not get zfs filesystem")
    81  	}
    82  
    83  	return filesystem, nil
    84  }
    85  
    86  func SummariesToImages(summaries []dockertypes.ImageSummary) ([]v1.DockerImage, error) {
    87  	var out []v1.DockerImage
    88  	const unknownTag = "<none>:<none>"
    89  	for _, summary := range summaries {
    90  		if len(summary.RepoTags) == 1 && summary.RepoTags[0] == unknownTag {
    91  			// images with repo or tags are uninteresting.
    92  			continue
    93  		}
    94  		di := v1.DockerImage{
    95  			ID:          summary.ID,
    96  			RepoTags:    summary.RepoTags,
    97  			Created:     summary.Created,
    98  			VirtualSize: summary.VirtualSize,
    99  			Size:        summary.Size,
   100  		}
   101  		out = append(out, di)
   102  	}
   103  	return out, nil
   104  }
   105  
   106  // Returns the ID from the full container name.
   107  func ContainerNameToId(name string) string {
   108  	id := path.Base(name)
   109  
   110  	if matches := cgroupRegexp.FindStringSubmatch(id); matches != nil {
   111  		return matches[1]
   112  	}
   113  
   114  	return id
   115  }
   116  
   117  // IsContainerName returns true if the cgroup with associated name
   118  // corresponds to a container.
   119  func IsContainerName(name string) bool {
   120  	// always ignore .mount cgroup even if associated with docker and delegate to systemd
   121  	if strings.HasSuffix(name, ".mount") {
   122  		return false
   123  	}
   124  	return cgroupRegexp.MatchString(path.Base(name))
   125  }