github.com/benz9527/xboot@v0.0.0-20240504061247-c23f15593274/lib/runtime/env_linux.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  package runtime
     5  
     6  import (
     7  	"bufio"
     8  	"fmt"
     9  	"io"
    10  	"os"
    11  	"regexp"
    12  )
    13  
    14  // 1. Loading '/proc/1/status' to check name whether is 'systemd'. If not,
    15  //   the application running in a docker or kubernetes env.
    16  //   It may occur access permission denied.
    17  // 2. Loading '/dev/block' directory, the container env default without block
    18  //   devices.
    19  
    20  const (
    21  	dockerEnvPath                = "/.dockerenv"                                             // unstable
    22  	dockerBlockPath              = "/dev/block"                                              // stable
    23  	kubernetesServiceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" // stable
    24  )
    25  
    26  func IsRunningAtDocker() bool {
    27  	// Must be contained in kubernetes env
    28  	stat, err := os.Stat(dockerEnvPath)
    29  	if err != nil && os.IsNotExist(err) {
    30  		if _, err = os.Stat(dockerBlockPath); err != nil && os.IsNotExist(err) {
    31  			return true
    32  		}
    33  		return false
    34  	}
    35  	if !stat.IsDir() {
    36  		return true
    37  	}
    38  	return false
    39  }
    40  
    41  func IsRunningAtKubernetes() bool {
    42  	// Must be contained in kubernetes env
    43  	stat, err := os.Stat(kubernetesServiceAccountPath)
    44  	if err != nil && os.IsNotExist(err) {
    45  		return false
    46  	}
    47  	if !stat.IsDir() && stat.Size() > 0 {
    48  		return true
    49  	}
    50  	return false
    51  }
    52  
    53  const (
    54  	uuidSource      = "[0-9a-f]{8}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{12}|[0-9a-f]{8}(?:-[0-9a-f]{4}){4}$"
    55  	containerSource = "[0-9a-f]{64}"
    56  	taskSource      = "[0-9a-f]{32}-\\d+"
    57  )
    58  
    59  var (
    60  	// /proc/self/cgroup line example:
    61  	// 0::/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pode6ac4a8d_1076_453e_9ddb_3976520e3178.slice/cri-containerd-19cd7a809d879d9c855bb93e4d399efe795a769ac856faaa5256cdd8387fe4b1.scope
    62  	procSelfCgroupLineRegex = regexp.MustCompile(`^\d+:[^:]*:(.+)$`)
    63  	containerIDRegex        = regexp.MustCompile(fmt.Sprintf(`(%s|%s|%s)(?:.scope)?$`, uuidSource, containerSource, taskSource))
    64  )
    65  
    66  func parseContainerID(r io.Reader) string {
    67  	scanner := bufio.NewScanner(r)
    68  	for scanner.Scan() {
    69  		path := procSelfCgroupLineRegex.FindStringSubmatch(scanner.Text())
    70  		if len(path) != 2 {
    71  			continue
    72  		}
    73  		if parts := containerIDRegex.FindStringSubmatch(path[1]); len(parts) == 2 {
    74  			return parts[1]
    75  		}
    76  	}
    77  	return ""
    78  }
    79  
    80  func LoadContainerID() string {
    81  	f, err := os.Open("/proc/self/cgroup")
    82  	if err != nil {
    83  		return ""
    84  	}
    85  	defer f.Close()
    86  	return parseContainerID(f)
    87  }