mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-01 11:56:29 +00:00
Change io/ioutil to io/os packages because io/ioutil package is deprecated from 1.16: Discard => io.Discard NopCloser => io.NopCloser ReadAll => io.ReadAll ReadDir => os.ReadDir ReadFile => os.ReadFile TempDir => os.MkdirTemp TempFile => os.CreateTemp WriteFile => os.WriteFile Details: https://go.dev/doc/go1.16#ioutil Fixes: #3265 Signed-off-by: bin <bin@hyper.sh>
136 lines
2.8 KiB
Go
136 lines
2.8 KiB
Go
// Copyright (c) 2018 Intel Corporation
|
|
// Copyright (c) 2018 HyperHQ Inc.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package katautils
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"syscall"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// validCIDRegex is a regular expression used to determine
|
|
// if a container ID (or sandbox ID) is valid.
|
|
const validCIDRegex = `^[a-zA-Z0-9][a-zA-Z0-9_.-]+$`
|
|
|
|
// FileExists test is a file exiting or not
|
|
func FileExists(path string) bool {
|
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// ResolvePath returns the fully resolved and expanded value of the
|
|
// specified path.
|
|
func ResolvePath(path string) (string, error) {
|
|
if path == "" {
|
|
return "", fmt.Errorf("path must be specified")
|
|
}
|
|
|
|
absolute, err := filepath.Abs(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
resolved, err := filepath.EvalSymlinks(absolute)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
// Make the error clearer than the default
|
|
return "", fmt.Errorf("file %v does not exist", absolute)
|
|
}
|
|
|
|
return "", err
|
|
}
|
|
|
|
return resolved, nil
|
|
}
|
|
|
|
// IsBlockDevice returns true if the give path is a block device
|
|
func IsBlockDevice(filePath string) bool {
|
|
var stat unix.Stat_t
|
|
|
|
if filePath == "" {
|
|
return false
|
|
}
|
|
|
|
devicePath, err := ResolvePath(filePath)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
if err := unix.Stat(devicePath, &stat); err != nil {
|
|
return false
|
|
}
|
|
|
|
if stat.Mode&unix.S_IFBLK == unix.S_IFBLK {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// fileSize returns the number of bytes in the specified file
|
|
func fileSize(file string) (int64, error) {
|
|
st := syscall.Stat_t{}
|
|
|
|
err := syscall.Stat(file, &st)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return st.Size, nil
|
|
}
|
|
|
|
// WriteFile write data into specified file
|
|
func WriteFile(filePath string, data string, fileMode os.FileMode) error {
|
|
// Normally dir should not be empty, one case is that cgroup subsystem
|
|
// is not mounted, we will get empty dir, and we want it fail here.
|
|
if filePath == "" {
|
|
return fmt.Errorf("no such file for %s", filePath)
|
|
}
|
|
|
|
if err := os.WriteFile(filePath, []byte(data), fileMode); err != nil {
|
|
return fmt.Errorf("failed to write %v to %v: %v", data, filePath, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetFileContents return the file contents as a string.
|
|
func GetFileContents(file string) (string, error) {
|
|
bytes, err := os.ReadFile(file)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return string(bytes), nil
|
|
}
|
|
|
|
// VerifyContainerID checks if the specified container ID
|
|
// (or sandbox ID) is valid.
|
|
func VerifyContainerID(id string) error {
|
|
if id == "" {
|
|
return errors.New("ID cannot be blank")
|
|
}
|
|
|
|
// Note: no length check.
|
|
validPattern := regexp.MustCompile(validCIDRegex)
|
|
|
|
matches := validPattern.MatchString(id)
|
|
|
|
if !matches {
|
|
return fmt.Errorf("invalid container/sandbox ID (should match %q)", validCIDRegex)
|
|
}
|
|
|
|
return nil
|
|
}
|