github.com/containerd/nerdctl@v1.7.7/pkg/infoutil/infoutil_unix.go (about)

     1  //go:build freebsd || linux
     2  
     3  /*
     4     Copyright The containerd Authors.
     5  
     6     Licensed under the Apache License, Version 2.0 (the "License");
     7     you may not use this file except in compliance with the License.
     8     You may obtain a copy of the License at
     9  
    10         http://www.apache.org/licenses/LICENSE-2.0
    11  
    12     Unless required by applicable law or agreed to in writing, software
    13     distributed under the License is distributed on an "AS IS" BASIS,
    14     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15     See the License for the specific language governing permissions and
    16     limitations under the License.
    17  */
    18  
    19  package infoutil
    20  
    21  import (
    22  	"bufio"
    23  	"io"
    24  	"os"
    25  	"regexp"
    26  
    27  	"strings"
    28  
    29  	"golang.org/x/sys/unix"
    30  )
    31  
    32  // UnameR returns `uname -r`
    33  func UnameR() string {
    34  	var utsname unix.Utsname
    35  	if err := unix.Uname(&utsname); err != nil {
    36  		// error is unlikely to happen
    37  		return ""
    38  	}
    39  	var s string
    40  	for _, f := range utsname.Release {
    41  		if f == 0 {
    42  			break
    43  		}
    44  		s += string(f)
    45  	}
    46  	return s
    47  }
    48  
    49  // UnameM returns `uname -m`
    50  func UnameM() string {
    51  	var utsname unix.Utsname
    52  	if err := unix.Uname(&utsname); err != nil {
    53  		// error is unlikely to happen
    54  		return ""
    55  	}
    56  	var s string
    57  	for _, f := range utsname.Machine {
    58  		if f == 0 {
    59  			break
    60  		}
    61  		s += string(f)
    62  	}
    63  	return s
    64  }
    65  
    66  func DistroName() string {
    67  	f, err := os.Open("/etc/os-release")
    68  	if err != nil {
    69  		return UnameO
    70  	}
    71  	defer f.Close()
    72  	return distroName(f)
    73  }
    74  
    75  func distroName(r io.Reader) string {
    76  	scanner := bufio.NewScanner(r)
    77  	var name, version string
    78  	for scanner.Scan() {
    79  		line := scanner.Text()
    80  		k, v := getOSReleaseAttrib(line)
    81  		switch k {
    82  		case "PRETTY_NAME":
    83  			return v
    84  		case "NAME":
    85  			name = v
    86  		case "VERSION":
    87  			version = v
    88  		}
    89  	}
    90  	if name != "" {
    91  		if version != "" {
    92  			return name + " " + version
    93  		}
    94  		return name
    95  	}
    96  	return UnameO
    97  }
    98  
    99  var osReleaseAttribRegex = regexp.MustCompile(`([^\s=]+)\s*=\s*("{0,1})([^"]*)("{0,1})`)
   100  
   101  func getOSReleaseAttrib(line string) (string, string) {
   102  	splitBySlash := strings.SplitN(line, "#", 2)
   103  	l := strings.TrimSpace(splitBySlash[0])
   104  	x := osReleaseAttribRegex.FindAllStringSubmatch(l, -1)
   105  	if len(x) >= 1 && len(x[0]) > 3 {
   106  		return x[0][1], x[0][3]
   107  	}
   108  	return "", ""
   109  }