gitee.com/leisunstar/runtime@v0.0.0-20200521203717-5cef3e7b53f9/pkg/katautils/utils.go (about)

     1  // Copyright (c) 2018 Intel Corporation
     2  // Copyright (c) 2018 HyperHQ Inc.
     3  //
     4  // SPDX-License-Identifier: Apache-2.0
     5  //
     6  
     7  package katautils
     8  
     9  import (
    10  	"fmt"
    11  	"golang.org/x/sys/unix"
    12  	"io/ioutil"
    13  	"os"
    14  	"os/exec"
    15  	"path/filepath"
    16  	"strings"
    17  	"syscall"
    18  )
    19  
    20  // FileExists test is a file exiting or not
    21  func FileExists(path string) bool {
    22  	if _, err := os.Stat(path); os.IsNotExist(err) {
    23  		return false
    24  	}
    25  
    26  	return true
    27  }
    28  
    29  // ResolvePath returns the fully resolved and expanded value of the
    30  // specified path.
    31  func ResolvePath(path string) (string, error) {
    32  	if path == "" {
    33  		return "", fmt.Errorf("path must be specified")
    34  	}
    35  
    36  	absolute, err := filepath.Abs(path)
    37  	if err != nil {
    38  		return "", err
    39  	}
    40  
    41  	resolved, err := filepath.EvalSymlinks(absolute)
    42  	if err != nil {
    43  		if os.IsNotExist(err) {
    44  			// Make the error clearer than the default
    45  			return "", fmt.Errorf("file %v does not exist", absolute)
    46  		}
    47  
    48  		return "", err
    49  	}
    50  
    51  	return resolved, nil
    52  }
    53  
    54  // IsBlockDevice returns true if the give path is a block device
    55  func IsBlockDevice(filePath string) bool {
    56  	var stat unix.Stat_t
    57  
    58  	if filePath == "" {
    59  		return false
    60  	}
    61  
    62  	devicePath, err := ResolvePath(filePath)
    63  	if err != nil {
    64  		return false
    65  	}
    66  
    67  	if err := unix.Stat(devicePath, &stat); err != nil {
    68  		return false
    69  	}
    70  
    71  	if stat.Mode&unix.S_IFBLK == unix.S_IFBLK {
    72  		return true
    73  	}
    74  	return false
    75  }
    76  
    77  // fileSize returns the number of bytes in the specified file
    78  func fileSize(file string) (int64, error) {
    79  	st := syscall.Stat_t{}
    80  
    81  	err := syscall.Stat(file, &st)
    82  	if err != nil {
    83  		return 0, err
    84  	}
    85  
    86  	return st.Size, nil
    87  }
    88  
    89  // WriteFile write data into specified file
    90  func WriteFile(filePath string, data string, fileMode os.FileMode) error {
    91  	// Normally dir should not be empty, one case is that cgroup subsystem
    92  	// is not mounted, we will get empty dir, and we want it fail here.
    93  	if filePath == "" {
    94  		return fmt.Errorf("no such file for %s", filePath)
    95  	}
    96  
    97  	if err := ioutil.WriteFile(filePath, []byte(data), fileMode); err != nil {
    98  		return fmt.Errorf("failed to write %v to %v: %v", data, filePath, err)
    99  	}
   100  
   101  	return nil
   102  }
   103  
   104  // GetFileContents return the file contents as a string.
   105  func GetFileContents(file string) (string, error) {
   106  	bytes, err := ioutil.ReadFile(file)
   107  	if err != nil {
   108  		return "", err
   109  	}
   110  
   111  	return string(bytes), nil
   112  }
   113  
   114  // RunCommandFull returns the commands space-trimmed standard output and
   115  // error on success. Note that if the command fails, the requested output will
   116  // still be returned, along with an error.
   117  func RunCommandFull(args []string, includeStderr bool) (string, error) {
   118  	cmd := exec.Command(args[0], args[1:]...)
   119  	var err error
   120  	var bytes []byte
   121  
   122  	if includeStderr {
   123  		bytes, err = cmd.CombinedOutput()
   124  	} else {
   125  		bytes, err = cmd.Output()
   126  	}
   127  
   128  	trimmed := strings.TrimSpace(string(bytes))
   129  
   130  	return trimmed, err
   131  }
   132  
   133  // RunCommand returns the commands space-trimmed standard output on success
   134  func RunCommand(args []string) (string, error) {
   135  	return RunCommandFull(args, false)
   136  }