diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 653c5c9fdbb..3eaeb3aeb03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - go-version: [1.15.x, 1.16.x, 1.17.x] + go-version: [1.16.x, 1.17.x] rootless: ["rootless", ""] race: ["-race", ""] criu: [""] @@ -119,7 +119,9 @@ jobs: sudo apt -q install libseccomp-dev libseccomp-dev:i386 gcc-multilib criu - name: install go - uses: actions/setup-go@v2 # use default Go version + uses: actions/setup-go@v2 + with: + go-version: 1.x # Latest stable - name: unit test # cgo is disabled by default when cross-compiling diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 0a812a5cd32..80a14db7419 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -30,6 +30,10 @@ jobs: CGO_CFLAGS: -g -O2 -Werror steps: - uses: actions/checkout@v2 + - name: install go + uses: actions/setup-go@v2 + with: + go-version: 1.x # Latest stable - name: compile with no build tags run: make BUILDTAGS="" @@ -93,6 +97,10 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 + - name: install go + uses: actions/setup-go@v2 + with: + go-version: 1.x # Latest stable - name: cache go mod and $GOCACHE uses: actions/cache@v2 with: diff --git a/README.md b/README.md index d7797653379..0d701a3452f 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ A third party security audit was performed by Cure53, you can see the full repor ## Building -`runc` only supports Linux. It must be built with Go version 1.15 or higher. +`runc` only supports Linux. It must be built with Go version 1.16 or higher. In order to enable seccomp support you will need to install `libseccomp` on your platform. > e.g. `libseccomp-devel` for CentOS, or `libseccomp-dev` for Ubuntu @@ -110,7 +110,7 @@ You can run a test using your container engine's flags by setting `CONTAINER_ENG `runc` uses [Go Modules](https://github.com/golang/go/wiki/Modules) for dependencies management. Please refer to [Go Modules](https://github.com/golang/go/wiki/Modules) for how to add or update -new dependencies. When updating dependencies, be sure that you are running Go `1.14` or newer. +new dependencies. ``` # Update vendored dependencies diff --git a/contrib/cmd/recvtty/recvtty.go b/contrib/cmd/recvtty/recvtty.go index 14f71154806..35c293de642 100644 --- a/contrib/cmd/recvtty/recvtty.go +++ b/contrib/cmd/recvtty/recvtty.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "strings" @@ -177,7 +176,7 @@ func handleNull(path string) error { return } - _, _ = io.Copy(ioutil.Discard, master) + _, _ = io.Copy(io.Discard, master) }(conn) } } @@ -225,7 +224,7 @@ func main() { pidPath := ctx.String("pid-file") if pidPath != "" { pid := fmt.Sprintf("%d\n", os.Getpid()) - if err := ioutil.WriteFile(pidPath, []byte(pid), 0o644); err != nil { + if err := os.WriteFile(pidPath, []byte(pid), 0o644); err != nil { return err } } diff --git a/contrib/cmd/seccompagent/seccompagent.go b/contrib/cmd/seccompagent/seccompagent.go index efc400c670c..9a6abc8f0b6 100644 --- a/contrib/cmd/seccompagent/seccompagent.go +++ b/contrib/cmd/seccompagent/seccompagent.go @@ -9,7 +9,6 @@ import ( "errors" "flag" "fmt" - "io/ioutil" "net" "os" "path/filepath" @@ -246,7 +245,7 @@ func main() { if pidFile != "" { pid := fmt.Sprintf("%d", os.Getpid()) - if err := ioutil.WriteFile(pidFile, []byte(pid), 0o644); err != nil { + if err := os.WriteFile(pidFile, []byte(pid), 0o644); err != nil { logrus.Fatalf("Cannot write pid file: %v", err) } } diff --git a/go.mod b/go.mod index 9442f1dd211..a57f29a4369 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/opencontainers/runc -go 1.15 +go 1.16 require ( github.com/checkpoint-restore/go-criu/v5 v5.1.0 diff --git a/libcontainer/apparmor/apparmor_linux.go b/libcontainer/apparmor/apparmor_linux.go index 17262913e0b..8b1483c7de7 100644 --- a/libcontainer/apparmor/apparmor_linux.go +++ b/libcontainer/apparmor/apparmor_linux.go @@ -3,7 +3,6 @@ package apparmor import ( "errors" "fmt" - "io/ioutil" "os" "sync" @@ -19,7 +18,7 @@ var ( func isEnabled() bool { checkAppArmor.Do(func() { if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil { - buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") + buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled") appArmorEnabled = err == nil && len(buf) > 1 && buf[0] == 'Y' } }) diff --git a/libcontainer/capabilities/capabilities_linux_test.go b/libcontainer/capabilities/capabilities_linux_test.go index 13a50e83349..dfbb44b4a3f 100644 --- a/libcontainer/capabilities/capabilities_linux_test.go +++ b/libcontainer/capabilities/capabilities_linux_test.go @@ -1,7 +1,7 @@ package capabilities import ( - "io/ioutil" + "io" "os" "testing" @@ -24,7 +24,7 @@ func TestNew(t *testing.T) { hook := test.NewGlobal() defer hook.Reset() - logrus.SetOutput(ioutil.Discard) + logrus.SetOutput(io.Discard) caps, err := New(&conf) logrus.SetOutput(os.Stderr) diff --git a/libcontainer/cgroups/fs/blkio_test.go b/libcontainer/cgroups/fs/blkio_test.go index 7810a67fc31..5f93cd0ad5b 100644 --- a/libcontainer/cgroups/fs/blkio_test.go +++ b/libcontainer/cgroups/fs/blkio_test.go @@ -258,7 +258,7 @@ func TestBlkioSetMultipleWeightDevice(t *testing.T) { wd1 := configs.NewWeightDevice(8, 0, 500, 0) wd2 := configs.NewWeightDevice(8, 16, 500, 0) - // we cannot actually set and check both because normal ioutil.WriteFile + // we cannot actually set and check both because normal os.WriteFile // when writing to cgroup file will overwrite the whole file content instead // of updating it as the kernel is doing. Just check the second device // is present will suffice for the test to ensure multiple writes are done. diff --git a/libcontainer/cgroups/fs2/io_test.go b/libcontainer/cgroups/fs2/io_test.go index d7ad1c56c97..15bb64a1d2d 100644 --- a/libcontainer/cgroups/fs2/io_test.go +++ b/libcontainer/cgroups/fs2/io_test.go @@ -1,7 +1,7 @@ package fs2 import ( - "io/ioutil" + "os" "path/filepath" "reflect" "sort" @@ -62,7 +62,7 @@ func TestStatIo(t *testing.T) { fakeCgroupDir := t.TempDir() statPath := filepath.Join(fakeCgroupDir, "io.stat") - if err := ioutil.WriteFile(statPath, []byte(exampleIoStatData), 0o644); err != nil { + if err := os.WriteFile(statPath, []byte(exampleIoStatData), 0o644); err != nil { t.Fatal(err) } diff --git a/libcontainer/cgroups/fscommon/utils_test.go b/libcontainer/cgroups/fscommon/utils_test.go index 6470a47a1c6..0339e998904 100644 --- a/libcontainer/cgroups/fscommon/utils_test.go +++ b/libcontainer/cgroups/fscommon/utils_test.go @@ -1,7 +1,6 @@ package fscommon import ( - "io/ioutil" "math" "os" "path/filepath" @@ -27,7 +26,7 @@ func TestGetCgroupParamsInt(t *testing.T) { tempFile := filepath.Join(tempDir, cgroupFile) // Success. - if err := ioutil.WriteFile(tempFile, []byte(floatString), 0o755); err != nil { + if err := os.WriteFile(tempFile, []byte(floatString), 0o755); err != nil { t.Fatal(err) } value, err := GetCgroupParamUint(tempDir, cgroupFile) @@ -38,7 +37,7 @@ func TestGetCgroupParamsInt(t *testing.T) { } // Success with new line. - err = ioutil.WriteFile(tempFile, []byte(floatString+"\n"), 0o755) + err = os.WriteFile(tempFile, []byte(floatString+"\n"), 0o755) if err != nil { t.Fatal(err) } @@ -50,7 +49,7 @@ func TestGetCgroupParamsInt(t *testing.T) { } // Success with negative values - err = ioutil.WriteFile(tempFile, []byte("-12345"), 0o755) + err = os.WriteFile(tempFile, []byte("-12345"), 0o755) if err != nil { t.Fatal(err) } @@ -63,7 +62,7 @@ func TestGetCgroupParamsInt(t *testing.T) { // Success with negative values lesser than min int64 s := strconv.FormatFloat(math.MinInt64, 'f', -1, 64) - err = ioutil.WriteFile(tempFile, []byte(s), 0o755) + err = os.WriteFile(tempFile, []byte(s), 0o755) if err != nil { t.Fatal(err) } @@ -75,7 +74,7 @@ func TestGetCgroupParamsInt(t *testing.T) { } // Not a float. - err = ioutil.WriteFile(tempFile, []byte("not-a-float"), 0o755) + err = os.WriteFile(tempFile, []byte("not-a-float"), 0o755) if err != nil { t.Fatal(err) } diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go index 3bab0e75a95..6c96882c680 100644 --- a/libcontainer/cgroups/utils.go +++ b/libcontainer/cgroups/utils.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -243,7 +242,7 @@ func RemovePath(path string) error { return nil } - infos, err := ioutil.ReadDir(path) + infos, err := os.ReadDir(path) if err != nil { if os.IsNotExist(err) { err = nil diff --git a/libcontainer/configs/config_test.go b/libcontainer/configs/config_test.go index ca825153fd0..5c29b747fce 100644 --- a/libcontainer/configs/config_test.go +++ b/libcontainer/configs/config_test.go @@ -3,7 +3,6 @@ package configs_test import ( "encoding/json" "fmt" - "io/ioutil" "os" "reflect" "testing" @@ -190,7 +189,7 @@ exit 0 verifyCommand := fmt.Sprintf(verifyCommandTemplate, stateJson) filename := "/tmp/runc-hooktest.sh" os.Remove(filename) - if err := ioutil.WriteFile(filename, []byte(verifyCommand), 0o700); err != nil { + if err := os.WriteFile(filename, []byte(verifyCommand), 0o700); err != nil { t.Fatalf("Failed to create tmp file: %v", err) } defer os.Remove(filename) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index df78a950f0a..50fa621475d 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "os/exec" @@ -286,7 +285,7 @@ func (c *linuxContainer) exec() error { } func readFromExecFifo(execFifo io.Reader) error { - data, err := ioutil.ReadAll(execFifo) + data, err := io.ReadAll(execFifo) if err != nil { return err } @@ -1151,7 +1150,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error { return err } - err = ioutil.WriteFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename), fdsJSON, 0o600) + err = os.WriteFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename), fdsJSON, 0o600) if err != nil { return err } @@ -1455,7 +1454,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error { fds []string fdJSON []byte ) - if fdJSON, err = ioutil.ReadFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename)); err != nil { + if fdJSON, err = os.ReadFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename)); err != nil { return err } @@ -1850,7 +1849,7 @@ func (c *linuxContainer) updateState(process parentProcess) (*State, error) { } func (c *linuxContainer) saveState(s *State) (retErr error) { - tmpFile, err := ioutil.TempFile(c.root, "state-") + tmpFile, err := os.CreateTemp(c.root, "state-") if err != nil { return err } @@ -2150,13 +2149,11 @@ func ignoreTerminateErrors(err error) error { if errors.As(err, &exitErr) { return nil } - // TODO: use errors.Is(err, os.ErrProcessDone) here and - // remove "process already finished" string comparison below - // once go 1.16 is minimally supported version. - + if errors.Is(err, os.ErrProcessDone) { + return nil + } s := err.Error() - if strings.Contains(s, "process already finished") || - strings.Contains(s, "Wait was already called") { + if strings.Contains(s, "Wait was already called") { return nil } return err diff --git a/libcontainer/devices/device_unix.go b/libcontainer/devices/device_unix.go index e2af4ff2cce..7d8e9fc3104 100644 --- a/libcontainer/devices/device_unix.go +++ b/libcontainer/devices/device_unix.go @@ -5,7 +5,6 @@ package devices import ( "errors" - "io/ioutil" "os" "path/filepath" @@ -17,8 +16,8 @@ var ErrNotADevice = errors.New("not a device node") // Testing dependencies var ( - unixLstat = unix.Lstat - ioutilReadDir = ioutil.ReadDir + unixLstat = unix.Lstat + osReadDir = os.ReadDir ) func mkDev(d *Rule) (uint64, error) { @@ -77,7 +76,7 @@ func HostDevices() ([]*Device, error) { // GetDevices recursively traverses a directory specified by path // and returns all devices found there. func GetDevices(path string) ([]*Device, error) { - files, err := ioutilReadDir(path) + files, err := osReadDir(path) if err != nil { return nil, err } diff --git a/libcontainer/devices/device_unix_go116_test.go b/libcontainer/devices/device_unix_go116_test.go new file mode 100644 index 00000000000..5e1cdf272de --- /dev/null +++ b/libcontainer/devices/device_unix_go116_test.go @@ -0,0 +1,39 @@ +//go:build !go1.17 +// +build !go1.17 + +package devices + +import "io/fs" + +// The following code is adapted from go1.17.1/src/io/fs/readdir.go +// to compensate for the lack of fs.FileInfoToDirEntry in Go 1.16. + +// dirInfo is a DirEntry based on a FileInfo. +type dirInfo struct { + fileInfo fs.FileInfo +} + +func (di dirInfo) IsDir() bool { + return di.fileInfo.IsDir() +} + +func (di dirInfo) Type() fs.FileMode { + return di.fileInfo.Mode().Type() +} + +func (di dirInfo) Info() (fs.FileInfo, error) { + return di.fileInfo, nil +} + +func (di dirInfo) Name() string { + return di.fileInfo.Name() +} + +// fileInfoToDirEntry returns a DirEntry that returns information from info. +// If info is nil, FileInfoToDirEntry returns nil. +func fileInfoToDirEntry(info fs.FileInfo) fs.DirEntry { + if info == nil { + return nil + } + return dirInfo{fileInfo: info} +} diff --git a/libcontainer/devices/device_unix_go117_test.go b/libcontainer/devices/device_unix_go117_test.go new file mode 100644 index 00000000000..d74db8f1598 --- /dev/null +++ b/libcontainer/devices/device_unix_go117_test.go @@ -0,0 +1,8 @@ +//go:build go1.17 +// +build go1.17 + +package devices + +import "io/fs" + +var fileInfoToDirEntry = fs.FileInfoToDirEntry diff --git a/libcontainer/devices/device_unix_test.go b/libcontainer/devices/device_unix_test.go index 9a93359f4ff..c58256cd0da 100644 --- a/libcontainer/devices/device_unix_test.go +++ b/libcontainer/devices/device_unix_test.go @@ -5,7 +5,7 @@ package devices import ( "errors" - "io/ioutil" + "io/fs" "os" "testing" @@ -14,7 +14,7 @@ import ( func cleanupTest() { unixLstat = unix.Lstat - ioutilReadDir = ioutil.ReadDir + osReadDir = os.ReadDir } func TestDeviceFromPathLstatFailure(t *testing.T) { @@ -35,8 +35,8 @@ func TestDeviceFromPathLstatFailure(t *testing.T) { func TestHostDevicesIoutilReadDirFailure(t *testing.T) { testError := errors.New("test error") - // Override ioutil.ReadDir to inject error. - ioutilReadDir = func(dirname string) ([]os.FileInfo, error) { + // Override os.ReadDir to inject error. + osReadDir = func(dirname string) ([]fs.DirEntry, error) { return nil, testError } defer cleanupTest() @@ -51,8 +51,8 @@ func TestHostDevicesIoutilReadDirDeepFailure(t *testing.T) { testError := errors.New("test error") called := false - // Override ioutil.ReadDir to inject error after the first call. - ioutilReadDir = func(dirname string) ([]os.FileInfo, error) { + // Override os.ReadDir to inject error after the first call. + osReadDir = func(dirname string) ([]fs.DirEntry, error) { if called { return nil, testError } @@ -64,7 +64,7 @@ func TestHostDevicesIoutilReadDirDeepFailure(t *testing.T) { t.Fatalf("Unexpected error %v", err) } - return []os.FileInfo{fi}, nil + return []fs.DirEntry{fileInfoToDirEntry(fi)}, nil } defer cleanupTest() diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index 9f7dc75f2e9..216e5efa97b 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "strings" @@ -358,7 +357,7 @@ func setupUser(config *initConfig) error { return err } - setgroups, err := ioutil.ReadFile("/proc/self/setgroups") + setgroups, err := os.ReadFile("/proc/self/setgroups") if err != nil && !os.IsNotExist(err) { return err } diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index 28f2e10d2c0..0c79c9f7e22 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -879,7 +878,7 @@ func TestMountCmds(t *testing.T) { // Wait for process waitProcess(&pconfig, t) - entries, err := ioutil.ReadDir(tmpDir) + entries, err := os.ReadDir(tmpDir) ok(t, err) expected := []string{"hello", "hello-backup", "world", "world-backup"} for i, e := range entries { diff --git a/libcontainer/intelrdt/intelrdt.go b/libcontainer/intelrdt/intelrdt.go index 62179f01f64..23931c5b1ff 100644 --- a/libcontainer/intelrdt/intelrdt.go +++ b/libcontainer/intelrdt/intelrdt.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -367,7 +366,7 @@ func parseCpuInfoFile(path string) (cpuInfoFlags, error) { // Gets a single uint64 value from the specified file. func getIntelRdtParamUint(path, file string) (uint64, error) { fileName := filepath.Join(path, file) - contents, err := ioutil.ReadFile(fileName) + contents, err := os.ReadFile(fileName) if err != nil { return 0, err } @@ -381,7 +380,7 @@ func getIntelRdtParamUint(path, file string) (uint64, error) { // Gets a string value from the specified file func getIntelRdtParamString(path, file string) (string, error) { - contents, err := ioutil.ReadFile(filepath.Join(path, file)) + contents, err := os.ReadFile(filepath.Join(path, file)) if err != nil { return "", err } @@ -393,7 +392,7 @@ func writeFile(dir, file, data string) error { if dir == "" { return fmt.Errorf("no such directory for %s", file) } - if err := ioutil.WriteFile(filepath.Join(dir, file), []byte(data+"\n"), 0o600); err != nil { + if err := os.WriteFile(filepath.Join(dir, file), []byte(data+"\n"), 0o600); err != nil { return newLastCmdError(fmt.Errorf("intelrdt: unable to write %v: %w", data, err)) } return nil @@ -488,7 +487,7 @@ func WriteIntelRdtTasks(dir string, pid int) error { // Don't attach any pid if -1 is specified as a pid if pid != -1 { - if err := ioutil.WriteFile(filepath.Join(dir, intelRdtTasks), []byte(strconv.Itoa(pid)), 0o600); err != nil { + if err := os.WriteFile(filepath.Join(dir, intelRdtTasks), []byte(strconv.Itoa(pid)), 0o600); err != nil { return newLastCmdError(fmt.Errorf("intelrdt: unable to add pid %d: %w", pid, err)) } } diff --git a/libcontainer/intelrdt/monitoring.go b/libcontainer/intelrdt/monitoring.go index 547c15470f2..82e0002efad 100644 --- a/libcontainer/intelrdt/monitoring.go +++ b/libcontainer/intelrdt/monitoring.go @@ -3,7 +3,6 @@ package intelrdt import ( "bufio" "io" - "io/ioutil" "os" "path/filepath" @@ -49,7 +48,7 @@ func parseMonFeatures(reader io.Reader) (monFeatures, error) { } func getMonitoringStats(containerPath string, stats *Stats) error { - numaFiles, err := ioutil.ReadDir(filepath.Join(containerPath, "mon_data")) + numaFiles, err := os.ReadDir(filepath.Join(containerPath, "mon_data")) if err != nil { return err } diff --git a/libcontainer/intelrdt/monitoring_test.go b/libcontainer/intelrdt/monitoring_test.go index 7685fa31bd2..0a89ef2f7b8 100644 --- a/libcontainer/intelrdt/monitoring_test.go +++ b/libcontainer/intelrdt/monitoring_test.go @@ -1,7 +1,6 @@ package intelrdt import ( - "io/ioutil" "os" "path/filepath" "strconv" @@ -51,7 +50,7 @@ func mockResctrlL3_MON(t *testing.T, NUMANodes []string, mocks map[string]uint64 } for fileName, value := range mocks { - err := ioutil.WriteFile(filepath.Join(numaPath, fileName), []byte(strconv.FormatUint(value, 10)), 0o644) + err := os.WriteFile(filepath.Join(numaPath, fileName), []byte(strconv.FormatUint(value, 10)), 0o644) if err != nil { t.Fatal(err) } diff --git a/libcontainer/logs/logs_linux_test.go b/libcontainer/logs/logs_linux_test.go index d6563fd2e0e..12640483b10 100644 --- a/libcontainer/logs/logs_linux_test.go +++ b/libcontainer/logs/logs_linux_test.go @@ -3,7 +3,6 @@ package logs import ( "bytes" "io" - "io/ioutil" "os" "testing" "time" @@ -93,7 +92,7 @@ func runLogForwarding(t *testing.T) *log { logW.Close() }) - tempFile, err := ioutil.TempFile("", "") + tempFile, err := os.CreateTemp("", "") if err != nil { t.Fatal(err) } @@ -129,7 +128,7 @@ func truncateLogFile(t *testing.T, file *os.File) { // check checks that the file contains txt and does not contain notxt. func check(t *testing.T, l *log, txt, notxt string) { t.Helper() - contents, err := ioutil.ReadFile(l.file.Name()) + contents, err := os.ReadFile(l.file.Name()) if err != nil { t.Fatal(err) } diff --git a/libcontainer/network_linux.go b/libcontainer/network_linux.go index aa2be8ffc17..8915548b3bc 100644 --- a/libcontainer/network_linux.go +++ b/libcontainer/network_linux.go @@ -3,7 +3,7 @@ package libcontainer import ( "bytes" "fmt" - "io/ioutil" + "os" "path/filepath" "strconv" @@ -73,7 +73,7 @@ func getNetworkInterfaceStats(interfaceName string) (*types.NetworkInterface, er // Reads the specified statistics available under /sys/class/net//statistics func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) { - data, err := ioutil.ReadFile(filepath.Join("/sys/class/net", ethInterface, "statistics", statsFile)) + data, err := os.ReadFile(filepath.Join("/sys/class/net", ethInterface, "statistics", statsFile)) if err != nil { return 0, err } diff --git a/libcontainer/notify_linux.go b/libcontainer/notify_linux.go index 0ec1a55c3f5..a8762842e8f 100644 --- a/libcontainer/notify_linux.go +++ b/libcontainer/notify_linux.go @@ -3,7 +3,6 @@ package libcontainer import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" @@ -33,7 +32,7 @@ func registerMemoryEvent(cgDir string, evName string, arg string) (<-chan struct eventControlPath := filepath.Join(cgDir, "cgroup.event_control") data := fmt.Sprintf("%d %d %s", eventfd.Fd(), evFile.Fd(), arg) - if err := ioutil.WriteFile(eventControlPath, []byte(data), 0o700); err != nil { + if err := os.WriteFile(eventControlPath, []byte(data), 0o700); err != nil { eventfd.Close() evFile.Close() return nil, err diff --git a/libcontainer/notify_linux_test.go b/libcontainer/notify_linux_test.go index cf0f90f4d2c..3967f07f007 100644 --- a/libcontainer/notify_linux_test.go +++ b/libcontainer/notify_linux_test.go @@ -3,7 +3,6 @@ package libcontainer import ( "encoding/binary" "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -18,10 +17,10 @@ func testMemoryNotification(t *testing.T, evName string, notify notifyFunc, targ memoryPath := t.TempDir() evFile := filepath.Join(memoryPath, evName) eventPath := filepath.Join(memoryPath, "cgroup.event_control") - if err := ioutil.WriteFile(evFile, []byte{}, 0o700); err != nil { + if err := os.WriteFile(evFile, []byte{}, 0o700); err != nil { t.Fatal(err) } - if err := ioutil.WriteFile(eventPath, []byte{}, 0o700); err != nil { + if err := os.WriteFile(eventPath, []byte{}, 0o700); err != nil { t.Fatal(err) } ch, err := notify(memoryPath) @@ -29,7 +28,7 @@ func testMemoryNotification(t *testing.T, evName string, notify notifyFunc, targ t.Fatal("expected no error, got:", err) } - data, err := ioutil.ReadFile(eventPath) + data, err := os.ReadFile(eventPath) if err != nil { t.Fatal("couldn't read event control file:", err) } diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 19bc96d55d0..72eb2b429d2 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path" @@ -182,7 +181,7 @@ func finalizeRootfs(config *configs.Config) (err error) { // /tmp has to be mounted as private to allow MS_MOVE to work in all situations func prepareTmp(topTmpDir string) (string, error) { - tmpdir, err := ioutil.TempDir(topTmpDir, "runctop") + tmpdir, err := os.MkdirTemp(topTmpDir, "runctop") if err != nil { return "", err } @@ -337,7 +336,7 @@ func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) { return fmt.Errorf("tmpcopyup: failed to setup tmpdir: %w", err) } defer cleanupTmp(tmpdir) - tmpDir, err := ioutil.TempDir(tmpdir, "runctmpdir") + tmpDir, err := os.MkdirTemp(tmpdir, "runctmpdir") if err != nil { return fmt.Errorf("tmpcopyup: failed to create tmpdir: %w", err) } @@ -1034,7 +1033,7 @@ func maskPath(path string, mountLabel string) error { // For e.g. net.ipv4.ip_forward translated to /proc/sys/net/ipv4/ip_forward. func writeSystemProperty(key, value string) error { keyPath := strings.Replace(key, ".", "/", -1) - return ioutil.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0o644) + return os.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0o644) } func remount(m *configs.Mount, rootfs string) error { diff --git a/libcontainer/system/proc.go b/libcontainer/system/proc.go index 8f0a68afd12..774443ec9d2 100644 --- a/libcontainer/system/proc.go +++ b/libcontainer/system/proc.go @@ -2,7 +2,7 @@ package system import ( "fmt" - "io/ioutil" + "os" "path/filepath" "strconv" "strings" @@ -67,7 +67,7 @@ type Stat_t struct { // Stat returns a Stat_t instance for the specified process. func Stat(pid int) (stat Stat_t, err error) { - bytes, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat")) + bytes, err := os.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat")) if err != nil { return stat, err } diff --git a/libcontainer/utils/utils_unix.go b/libcontainer/utils/utils_unix.go index 3b303e189ef..220d0b43937 100644 --- a/libcontainer/utils/utils_unix.go +++ b/libcontainer/utils/utils_unix.go @@ -53,7 +53,7 @@ func CloseExecFrom(minFd int) error { // Intentionally ignore errors from unix.CloseOnExec -- the cases where // this might fail are basically file descriptors that have already // been closed (including and especially the one that was created when - // ioutil.ReadDir did the "opendir" syscall). + // os.ReadDir did the "opendir" syscall). unix.CloseOnExec(fd) } return nil diff --git a/list.go b/list.go index 38d9869d41b..3503dcd2f5e 100644 --- a/list.go +++ b/list.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "path/filepath" "syscall" @@ -121,7 +120,7 @@ func getContainers(context *cli.Context) ([]containerState, error) { if err != nil { return nil, err } - list, err := ioutil.ReadDir(absRoot) + list, err := os.ReadDir(absRoot) if err != nil { fatal(err) } @@ -129,11 +128,15 @@ func getContainers(context *cli.Context) ([]containerState, error) { var s []containerState for _, item := range list { if item.IsDir() { + st, err := os.Stat(filepath.Join(absRoot, item.Name())) + if err != nil { + fatal(err) + } // This cast is safe on Linux. - stat := item.Sys().(*syscall.Stat_t) - owner, err := user.LookupUid(int(stat.Uid)) + uid := st.Sys().(*syscall.Stat_t).Uid + owner, err := user.LookupUid(int(uid)) if err != nil { - owner.Name = fmt.Sprintf("#%d", stat.Uid) + owner.Name = fmt.Sprintf("#%d", uid) } container, err := factory.Load(item.Name()) diff --git a/spec.go b/spec.go index 87d6ebea871..806d2f15f86 100644 --- a/spec.go +++ b/spec.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "fmt" - "io/ioutil" "os" "github.com/opencontainers/runc/libcontainer/configs" @@ -109,7 +108,7 @@ created by an unprivileged user. if err != nil { return err } - return ioutil.WriteFile(specConfig, data, 0o666) + return os.WriteFile(specConfig, data, 0o666) }, }