From 9fe64a23fe9eff2716da740f841a96938fc9aafd Mon Sep 17 00:00:00 2001 From: dayshappy Date: Sat, 8 Apr 2023 16:39:26 +0800 Subject: [PATCH] [Backport]Prepare for Go 1.19 upgrade reference: https://github.com/moby/moby/pull/45073/commits Signed-off-by: dayshappy --- ...update-containerd-binary-to-v1.6.16.patch} | 0 ...onfigure-code-dir-as-safe-directory.patch} | 0 ...-from-io-ioutil-to-io-and-os-package.patch | 14189 ++++++++++++++++ ...existent-directories-from-golangci-l.patch | 28 + ...ck-do-not-exclude-SQL-related-checks.patch | 31 + ...ack-remove-a-workaround-for-go-tools.patch | 33 + ...rings-should-not-be-capitalized-revi.patch | 72 + ...y20.10-fix-some-minor-linting-issues.patch | 76 + ...hack-update-golangci-lint-to-v1.46.2.patch | 41 + ...olint-with-revive-as-it-s-deprecated.patch | 83 + ....10-gofmt-GoDoc-comments-with-go1.19.patch | 1807 ++ ...formatting-of-nolint-tags-for-go1.19.patch | 64 + ...x-or-suppress-G112-G114-in-test-code.patch | 202 + ...t-in-url-should-be-constructed-with-.patch | 80 + ...meout-to-address-G112-Potential-Slow.patch | 108 + ...0.10-golangci-lint-update-to-v1.49.0.patch | 115 + series.conf | 18 +- 17 files changed, 16945 insertions(+), 2 deletions(-) rename patch/{backport-0001-20.10-update-containerd-binary-to-v1.6.16.patch => backport-0001-moby20.10-update-containerd-binary-to-v1.6.16.patch} (100%) rename patch/{backport-0001-Dockerfile-configure-code-dir-as-safe-directory.patch => backport-0002-moby20.10-Dockerfile-configure-code-dir-as-safe-directory.patch} (100%) create mode 100644 patch/backport-0003-moby20.10-refactor-move-from-io-ioutil-to-io-and-os-package.patch create mode 100644 patch/backport-0004-moby20.10-hack-remove-non-existent-directories-from-golangci-l.patch create mode 100644 patch/backport-0005-moby20.10-hack-do-not-exclude-SQL-related-checks.patch create mode 100644 patch/backport-0006-moby20.10-hack-remove-a-workaround-for-go-tools.patch create mode 100644 patch/backport-0007-moby20.10-linting-error-strings-should-not-be-capitalized-revi.patch create mode 100644 patch/backport-0008-moby20.10-fix-some-minor-linting-issues.patch create mode 100644 patch/backport-0009-moby20.10-hack-update-golangci-lint-to-v1.46.2.patch create mode 100644 patch/backport-0010-moby20.10-replace-golint-with-revive-as-it-s-deprecated.patch create mode 100644 patch/backport-0011-moby20.10-gofmt-GoDoc-comments-with-go1.19.patch create mode 100644 patch/backport-0012-moby20.10-fix-formatting-of-nolint-tags-for-go1.19.patch create mode 100644 patch/backport-0013-moby20.10-linting-gosec-fix-or-suppress-G112-G114-in-test-code.patch create mode 100644 patch/backport-0014-moby20.10-linting-host-port-in-url-should-be-constructed-with-.patch create mode 100644 patch/backport-0015-moby20.10-set-ReadHeaderTimeout-to-address-G112-Potential-Slow.patch create mode 100644 patch/backport-0016-moby20.10-golangci-lint-update-to-v1.49.0.patch diff --git a/patch/backport-0001-20.10-update-containerd-binary-to-v1.6.16.patch b/patch/backport-0001-moby20.10-update-containerd-binary-to-v1.6.16.patch similarity index 100% rename from patch/backport-0001-20.10-update-containerd-binary-to-v1.6.16.patch rename to patch/backport-0001-moby20.10-update-containerd-binary-to-v1.6.16.patch diff --git a/patch/backport-0001-Dockerfile-configure-code-dir-as-safe-directory.patch b/patch/backport-0002-moby20.10-Dockerfile-configure-code-dir-as-safe-directory.patch similarity index 100% rename from patch/backport-0001-Dockerfile-configure-code-dir-as-safe-directory.patch rename to patch/backport-0002-moby20.10-Dockerfile-configure-code-dir-as-safe-directory.patch diff --git a/patch/backport-0003-moby20.10-refactor-move-from-io-ioutil-to-io-and-os-package.patch b/patch/backport-0003-moby20.10-refactor-move-from-io-ioutil-to-io-and-os-package.patch new file mode 100644 index 0000000..8a8bed9 --- /dev/null +++ b/patch/backport-0003-moby20.10-refactor-move-from-io-ioutil-to-io-and-os-package.patch @@ -0,0 +1,14189 @@ +From a916414b0bf9e1641d65adf066b769806e0d623a Mon Sep 17 00:00:00 2001 +From: Eng Zer Jun +Date: Tue, 24 Aug 2021 18:10:50 +0800 +Subject: [PATCH 03/16] refactor: move from io/ioutil to io and os package + +The io/ioutil package has been deprecated in Go 1.16. This commit +replaces the existing io/ioutil functions with their new definitions in +io and os packages. + +Signed-off-by: Eng Zer Jun +(cherry picked from commit c55a4ac7795c7606b548b38e24673733481e2167) +Signed-off-by: Cory Snider +--- + .../adapters/containerimage/pull.go | 3 +- + builder/builder-next/executor_unix.go | 3 +- + builder/builder-next/worker/worker.go | 3 +- + builder/dockerfile/builder.go | 5 +- + builder/dockerfile/utils_test.go | 5 +- + builder/remotecontext/detect_test.go | 5 +- + builder/remotecontext/git/gitutils.go | 3 +- + builder/remotecontext/remote.go | 3 +- + builder/remotecontext/remote_test.go | 29 +++--- + builder/remotecontext/tarsum_test.go | 3 +- + builder/remotecontext/utils_test.go | 7 +- + client/checkpoint_create_test.go | 4 +- + client/checkpoint_delete_test.go | 4 +- + client/checkpoint_list_test.go | 4 +- + client/client_mock_test.go | 6 +- + client/client_test.go | 4 +- + client/config_create_test.go | 4 +- + client/config_inspect.go | 4 +- + client/config_inspect_test.go | 4 +- + client/config_list_test.go | 4 +- + client/config_remove_test.go | 4 +- + client/config_update_test.go | 4 +- + client/container_commit_test.go | 4 +- + client/container_copy_test.go | 16 ++-- + client/container_create_test.go | 6 +- + client/container_diff_test.go | 4 +- + client/container_exec_test.go | 8 +- + client/container_export_test.go | 6 +- + client/container_inspect.go | 4 +- + client/container_inspect_test.go | 6 +- + client/container_kill_test.go | 4 +- + client/container_list_test.go | 4 +- + client/container_logs_test.go | 5 +- + client/container_pause_test.go | 4 +- + client/container_prune_test.go | 4 +- + client/container_remove_test.go | 4 +- + client/container_rename_test.go | 4 +- + client/container_resize_test.go | 4 +- + client/container_restart_test.go | 4 +- + client/container_start_test.go | 4 +- + client/container_stats_test.go | 6 +- + client/container_stop_test.go | 4 +- + client/container_top_test.go | 4 +- + client/container_unpause_test.go | 4 +- + client/container_update_test.go | 4 +- + client/container_wait_test.go | 4 +- + client/disk_usage_test.go | 4 +- + client/events_test.go | 3 +- + client/hijack_test.go | 4 +- + client/image_build_test.go | 6 +- + client/image_create_test.go | 6 +- + client/image_history_test.go | 4 +- + client/image_import_test.go | 6 +- + client/image_inspect.go | 4 +- + client/image_inspect_test.go | 4 +- + client/image_list_test.go | 6 +- + client/image_load_test.go | 6 +- + client/image_prune_test.go | 4 +- + client/image_pull_test.go | 12 +-- + client/image_push_test.go | 12 +-- + client/image_remove_test.go | 4 +- + client/image_save_test.go | 6 +- + client/image_search_test.go | 8 +- + client/image_tag_test.go | 4 +- + client/info_test.go | 6 +- + client/network_connect_test.go | 6 +- + client/network_create_test.go | 4 +- + client/network_disconnect_test.go | 4 +- + client/network_inspect.go | 4 +- + client/network_inspect_test.go | 6 +- + client/network_list_test.go | 4 +- + client/network_prune_test.go | 4 +- + client/network_remove_test.go | 4 +- + client/node_inspect.go | 4 +- + client/node_inspect_test.go | 4 +- + client/node_list_test.go | 4 +- + client/node_remove_test.go | 4 +- + client/node_update_test.go | 4 +- + client/ping_test.go | 8 +- + client/plugin_disable_test.go | 4 +- + client/plugin_enable_test.go | 4 +- + client/plugin_inspect.go | 4 +- + client/plugin_inspect_test.go | 4 +- + client/plugin_list_test.go | 4 +- + client/plugin_push_test.go | 4 +- + client/plugin_remove_test.go | 4 +- + client/plugin_set_test.go | 4 +- + client/request.go | 5 +- + client/request_test.go | 6 +- + client/secret_create_test.go | 4 +- + client/secret_inspect.go | 4 +- + client/secret_inspect_test.go | 4 +- + client/secret_list_test.go | 4 +- + client/secret_remove_test.go | 4 +- + client/secret_update_test.go | 4 +- + client/service_create_test.go | 12 +-- + client/service_inspect.go | 4 +- + client/service_inspect_test.go | 4 +- + client/service_list_test.go | 4 +- + client/service_logs_test.go | 5 +- + client/service_remove_test.go | 4 +- + client/service_update_test.go | 4 +- + client/swarm_get_unlock_key_test.go | 4 +- + client/swarm_init_test.go | 4 +- + client/swarm_inspect_test.go | 4 +- + client/swarm_join_test.go | 4 +- + client/swarm_leave_test.go | 4 +- + client/swarm_unlock_test.go | 4 +- + client/swarm_update_test.go | 4 +- + client/task_inspect.go | 4 +- + client/task_inspect_test.go | 4 +- + client/task_list_test.go | 4 +- + client/volume_create_test.go | 4 +- + client/volume_inspect.go | 4 +- + client/volume_inspect_test.go | 4 +- + client/volume_list_test.go | 4 +- + client/volume_remove_test.go | 4 +- + cmd/dockerd/service_windows.go | 4 +- + container/container_unit_test.go | 5 +- + container/container_unix.go | 5 +- + container/stream/streams.go | 3 +- + container/view_test.go | 3 +- + daemon/checkpoint.go | 3 +- + .../cluster/controllers/plugin/controller.go | 5 +- + .../controllers/plugin/controller_test.go | 3 +- + .../executor/container/validate_test.go | 5 +- + daemon/cluster/utils.go | 5 +- + daemon/config/config.go | 3 +- + daemon/config/config_test.go | 13 ++- + daemon/config/config_windows_test.go | 4 +- + daemon/container_operations_unix.go | 5 +- + daemon/container_operations_windows.go | 5 +- + daemon/daemon.go | 5 +- + daemon/daemon_linux_test.go | 5 +- + daemon/daemon_test.go | 7 +- + daemon/daemon_unix.go | 9 +- + daemon/daemon_unix_test.go | 7 +- + daemon/delete_test.go | 3 +- + daemon/graphdriver/aufs/aufs.go | 9 +- + daemon/graphdriver/aufs/aufs_test.go | 3 +- + daemon/graphdriver/aufs/dirs.go | 3 +- + daemon/graphdriver/btrfs/btrfs.go | 5 +- + daemon/graphdriver/copy/copy_test.go | 19 ++-- + daemon/graphdriver/devmapper/device_setup.go | 7 +- + daemon/graphdriver/devmapper/deviceset.go | 17 ++-- + daemon/graphdriver/devmapper/driver.go | 3 +- + daemon/graphdriver/driver_test.go | 5 +- + .../fuse-overlayfs/fuseoverlayfs.go | 19 ++-- + .../graphdriver/graphtest/graphbench_unix.go | 7 +- + .../graphdriver/graphtest/graphtest_unix.go | 5 +- + daemon/graphdriver/lcow/lcow.go | 7 +- + daemon/graphdriver/overlay/overlay.go | 13 ++- + daemon/graphdriver/overlay2/check.go | 5 +- + daemon/graphdriver/overlay2/overlay.go | 19 ++-- + daemon/graphdriver/overlay2/overlay_test.go | 3 +- + .../graphdriver/overlayutils/overlayutils.go | 3 +- + daemon/graphdriver/overlayutils/userxattr.go | 3 +- + daemon/graphdriver/windows/windows.go | 11 +-- + daemon/images/image.go | 5 +- + daemon/images/store_test.go | 3 +- + daemon/keys.go | 3 +- + daemon/list_test.go | 3 +- + daemon/logger/awslogs/cloudwatchlogs_test.go | 3 +- + daemon/logger/jsonfilelog/jsonfilelog_test.go | 24 ++--- + daemon/logger/local/local_test.go | 7 +- + daemon/logger/local/read_test.go | 3 +- + .../logger/loggerutils/file_windows_test.go | 5 +- + daemon/logger/loggerutils/logfile_test.go | 18 ++-- + daemon/logger/splunk/splunk.go | 11 +-- + daemon/logger/splunk/splunkhecmock_test.go | 3 +- + daemon/oci_linux.go | 3 +- + daemon/oci_linux_test.go | 3 +- + daemon/oci_windows.go | 4 +- + daemon/oci_windows_test.go | 3 +- + daemon/runtime_unix.go | 3 +- + daemon/trustkey_test.go | 5 +- + distribution/manifest.go | 3 +- + distribution/manifest_test.go | 3 +- + distribution/metadata/metadata.go | 3 +- + distribution/metadata/v1_id_service_test.go | 3 +- + .../metadata/v2_metadata_service_test.go | 3 +- + distribution/pull_v2.go | 3 +- + distribution/pull_v2_test.go | 8 +- + distribution/xfer/download_test.go | 5 +- + image/fs.go | 7 +- + image/fs_test.go | 9 +- + image/tarexport/load.go | 9 +- + image/tarexport/save.go | 9 +- + integration-cli/benchmark_test.go | 3 +- + integration-cli/check_test.go | 3 +- + integration-cli/docker_api_build_test.go | 5 +- + integration-cli/docker_api_containers_test.go | 15 ++- + .../docker_api_containers_windows_test.go | 4 +- + integration-cli/docker_api_exec_test.go | 10 +- + integration-cli/docker_api_logs_test.go | 5 +- + integration-cli/docker_api_swarm_test.go | 4 +- + integration-cli/docker_api_test.go | 4 +- + .../docker_cli_attach_unix_test.go | 4 +- + integration-cli/docker_cli_build_test.go | 79 ++++++++-------- + integration-cli/docker_cli_build_unix_test.go | 5 +- + integration-cli/docker_cli_cp_test.go | 72 +++++++------- + integration-cli/docker_cli_cp_utils_test.go | 10 +- + integration-cli/docker_cli_daemon_test.go | 49 +++++----- + integration-cli/docker_cli_events_test.go | 3 +- + .../docker_cli_events_unix_test.go | 9 +- + .../docker_cli_external_volume_driver_test.go | 9 +- + integration-cli/docker_cli_images_test.go | 5 +- + integration-cli/docker_cli_import_test.go | 9 +- + integration-cli/docker_cli_logout_test.go | 17 ++-- + .../docker_cli_network_unix_test.go | 5 +- + integration-cli/docker_cli_plugins_test.go | 12 +-- + integration-cli/docker_cli_prune_unix_test.go | 9 +- + integration-cli/docker_cli_pull_local_test.go | 19 ++-- + integration-cli/docker_cli_push_test.go | 3 +- + .../docker_cli_registry_user_agent_test.go | 3 +- + integration-cli/docker_cli_run_test.go | 69 +++++++------- + integration-cli/docker_cli_run_unix_test.go | 33 ++++--- + integration-cli/docker_cli_save_load_test.go | 7 +- + .../docker_cli_save_load_unix_test.go | 3 +- + integration-cli/docker_cli_sni_test.go | 4 +- + integration-cli/docker_cli_swarm_test.go | 15 ++- + integration-cli/docker_cli_userns_test.go | 3 +- + integration-cli/docker_cli_v2_only_test.go | 7 +- + integration-cli/docker_cli_volume_test.go | 5 +- + integration-cli/docker_utils_test.go | 9 +- + integration-cli/fixtures_linux_daemon_test.go | 9 +- + integration-cli/requirements_test.go | 3 +- + integration-cli/requirements_unix_test.go | 4 +- + integration/build/build_session_test.go | 4 +- + integration/build/build_squash_test.go | 7 +- + integration/build/build_test.go | 20 ++-- + integration/build/build_userns_linux_test.go | 5 +- + integration/config/config_test.go | 6 +- + integration/container/copy_test.go | 7 +- + integration/container/daemon_linux_test.go | 8 +- + integration/container/exec_test.go | 6 +- + integration/container/ipcmode_linux_test.go | 3 +- + integration/container/links_linux_test.go | 3 +- + integration/container/logs_test.go | 4 +- + integration/container/nat_test.go | 5 +- + integration/image/pull_test.go | 3 +- + integration/image/remove_unix_test.go | 5 +- + integration/plugin/authz/authz_plugin_test.go | 11 +-- + .../plugin/authz/authz_plugin_v2_test.go | 4 +- + integration/plugin/authz/main_test.go | 6 +- + integration/plugin/common/plugin_test.go | 13 ++- + .../plugin/graphdriver/external_test.go | 9 +- + .../plugin/logging/cmd/discard/driver.go | 3 +- + integration/plugin/volumes/mounts_test.go | 3 +- + integration/service/create_test.go | 6 +- + integration/service/plugin_test.go | 5 +- + layer/empty.go | 3 +- + layer/filestore.go | 35 ++++--- + layer/filestore_test.go | 9 +- + layer/filestore_windows.go | 3 +- + layer/layer_store.go | 3 +- + layer/layer_test.go | 11 +-- + layer/migration_test.go | 9 +- + layer/mount_test.go | 6 +- + libcontainerd/local/local_windows.go | 6 +- + libcontainerd/supervisor/remote_daemon.go | 3 +- + oci/seccomp_test.go | 4 +- + pkg/archive/archive.go | 3 +- + pkg/archive/archive_linux_test.go | 13 ++- + pkg/archive/archive_test.go | 93 +++++++++---------- + pkg/archive/archive_unix_test.go | 32 +++---- + pkg/archive/archive_windows_test.go | 5 +- + pkg/archive/changes.go | 3 +- + pkg/archive/changes_posix_test.go | 5 +- + pkg/archive/changes_test.go | 53 ++++++----- + pkg/archive/copy.go | 3 +- + pkg/archive/copy_unix_test.go | 5 +- + pkg/archive/diff.go | 3 +- + pkg/archive/diff_test.go | 7 +- + pkg/archive/example_changes.go | 7 +- + pkg/archive/utils_test.go | 9 +- + pkg/authorization/authz_unix_test.go | 10 +- + pkg/chrootarchive/archive.go | 3 +- + pkg/chrootarchive/archive_test.go | 35 ++++--- + pkg/chrootarchive/archive_unix.go | 3 +- + pkg/chrootarchive/archive_unix_test.go | 15 ++- + pkg/chrootarchive/chroot_linux.go | 3 +- + pkg/chrootarchive/diff_unix.go | 3 +- + pkg/chrootarchive/diff_windows.go | 3 +- + pkg/chrootarchive/init_unix.go | 3 +- + pkg/directory/directory.go | 3 +- + pkg/directory/directory_test.go | 35 ++++--- + pkg/discovery/file/file.go | 4 +- + pkg/discovery/file/file_test.go | 5 +- + pkg/discovery/kv/kv_test.go | 5 +- + pkg/filenotify/poller_test.go | 9 +- + pkg/fileutils/fileutils_test.go | 27 +++--- + pkg/fileutils/fileutils_unix.go | 3 +- + pkg/fsutils/fsutils_linux.go | 5 +- + pkg/fsutils/fsutils_linux_test.go | 5 +- + pkg/idtools/idtools_unix_test.go | 17 ++-- + pkg/ioutils/fswriters.go | 5 +- + pkg/ioutils/fswriters_test.go | 15 ++- + pkg/ioutils/readers_test.go | 4 +- + pkg/ioutils/temp_unix.go | 6 +- + pkg/ioutils/temp_windows.go | 6 +- + .../operatingsystem/operatingsystem_linux.go | 3 +- + .../operatingsystem_linux_test.go | 13 ++- + pkg/pidfile/pidfile.go | 5 +- + pkg/pidfile/pidfile_test.go | 3 +- + pkg/plugins/client.go | 3 +- + pkg/plugins/discovery.go | 22 +++-- + pkg/plugins/discovery_test.go | 9 +- + pkg/plugins/discovery_unix_test.go | 3 +- + pkg/plugins/plugin_test.go | 4 +- + pkg/plugins/pluginrpc-gen/main.go | 3 +- + pkg/progress/progressreader_test.go | 7 +- + pkg/signal/trap_linux_test.go | 7 +- + pkg/stdcopy/stdcopy_test.go | 27 +++--- + pkg/sysinfo/cgroup2_linux.go | 5 +- + pkg/sysinfo/sysinfo_linux.go | 9 +- + pkg/sysinfo/sysinfo_linux_test.go | 11 +-- + pkg/system/chtimes_test.go | 5 +- + pkg/system/filesys_unix.go | 3 +- + pkg/system/filesys_windows.go | 2 +- + pkg/system/process_unix.go | 4 +- + pkg/system/rm_nodarwin_test.go | 6 +- + pkg/system/rm_test.go | 5 +- + pkg/system/utimes_unix_test.go | 5 +- + pkg/tailfile/tailfile_test.go | 15 ++- + pkg/tarsum/builder_context_test.go | 5 +- + pkg/tarsum/tarsum_test.go | 15 ++- + plugin/backend_linux.go | 11 +-- + plugin/backend_linux_test.go | 7 +- + plugin/manager.go | 5 +- + plugin/manager_linux_test.go | 9 +- + profiles/apparmor/apparmor.go | 5 +- + profiles/seccomp/generate.go | 3 +- + profiles/seccomp/seccomp_test.go | 12 +-- + quota/projectquota.go | 6 +- + quota/projectquota_test.go | 5 +- + quota/testhelpers.go | 7 +- + reference/store_test.go | 11 +-- + registry/endpoint_v1.go | 4 +- + registry/registry.go | 7 +- + registry/registry_mock_test.go | 5 +- + .../resumable/resumablerequestreader_test.go | 9 +- + rootless/specconv/specconv_linux.go | 4 +- + runconfig/config_test.go | 4 +- + runconfig/hostconfig_test.go | 4 +- + testutil/daemon/daemon.go | 3 +- + testutil/fakecontext/context.go | 5 +- + testutil/fakegit/fakegit.go | 3 +- + testutil/fakestorage/fixtures.go | 5 +- + testutil/fakestorage/storage.go | 3 +- + testutil/fixtures/plugin/plugin.go | 9 +- + testutil/registry/registry.go | 11 +-- + testutil/request/ops.go | 5 +- + testutil/request/request.go | 3 +- + volume/local/local.go | 7 +- + volume/local/local_linux_test.go | 5 +- + volume/local/local_test.go | 15 ++- + volume/mounts/parser_test.go | 3 +- + volume/mounts/validate_test.go | 3 +- + volume/service/db_test.go | 3 +- + volume/service/restore_test.go | 3 +- + volume/service/service_linux_test.go | 7 +- + volume/service/service_test.go | 3 +- + volume/service/store_test.go | 5 +- + 364 files changed, 1242 insertions(+), 1453 deletions(-) + +diff --git a/builder/builder-next/adapters/containerimage/pull.go b/builder/builder-next/adapters/containerimage/pull.go +index 7a5a4e1424..0926b36ade 100644 +--- a/builder/builder-next/adapters/containerimage/pull.go ++++ b/builder/builder-next/adapters/containerimage/pull.go +@@ -5,7 +5,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "path" + "runtime" + "sync" +@@ -641,7 +640,7 @@ func (ld *layerDescriptor) Download(ctx context.Context, progressOutput pkgprogr + return nil, 0, err + } + +- return ioutil.NopCloser(content.NewReader(ra)), ld.desc.Size, nil ++ return io.NopCloser(content.NewReader(ra)), ld.desc.Size, nil + } + + func (ld *layerDescriptor) Close() { +diff --git a/builder/builder-next/executor_unix.go b/builder/builder-next/executor_unix.go +index ad8377dc83..1029be286e 100644 +--- a/builder/builder-next/executor_unix.go ++++ b/builder/builder-next/executor_unix.go +@@ -4,7 +4,6 @@ + package buildkit + + import ( +- "io/ioutil" + "os" + "path/filepath" + "strconv" +@@ -35,7 +34,7 @@ func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dn + } + + // make sure net state directory is cleared from previous state +- fis, err := ioutil.ReadDir(netRoot) ++ fis, err := os.ReadDir(netRoot) + if err == nil { + for _, fi := range fis { + fp := filepath.Join(netRoot, fi.Name()) +diff --git a/builder/builder-next/worker/worker.go b/builder/builder-next/worker/worker.go +index 4dcf1bb882..445aeed96b 100644 +--- a/builder/builder-next/worker/worker.go ++++ b/builder/builder-next/worker/worker.go +@@ -4,7 +4,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + nethttp "net/http" + "runtime" + "strings" +@@ -442,7 +441,7 @@ func (ld *layerDescriptor) Download(ctx context.Context, progressOutput pkgprogr + return nil, 0, err + } + +- return ioutil.NopCloser(content.NewReader(ra)), ld.desc.Size, nil ++ return io.NopCloser(content.NewReader(ra)), ld.desc.Size, nil + } + + func (ld *layerDescriptor) Close() { +diff --git a/builder/dockerfile/builder.go b/builder/dockerfile/builder.go +index 03d8112427..10f81b79e1 100644 +--- a/builder/dockerfile/builder.go ++++ b/builder/dockerfile/builder.go +@@ -5,7 +5,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "sort" + "strings" + +@@ -349,8 +348,8 @@ func BuildFromConfig(config *container.Config, changes []string, os string) (*co + } + } + +- b.Stdout = ioutil.Discard +- b.Stderr = ioutil.Discard ++ b.Stdout = io.Discard ++ b.Stderr = io.Discard + b.disableCommit = true + + var commands []instructions.Command +diff --git a/builder/dockerfile/utils_test.go b/builder/dockerfile/utils_test.go +index 3d615f3460..98bdda2a7e 100644 +--- a/builder/dockerfile/utils_test.go ++++ b/builder/dockerfile/utils_test.go +@@ -1,7 +1,6 @@ + package dockerfile // import "github.com/docker/docker/builder/dockerfile" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -11,7 +10,7 @@ import ( + // It returns the created path and a cleanup function which is meant to be used as deferred call. + // When an error occurs, it terminates the test. + func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) { +- path, err := ioutil.TempDir(dir, prefix) ++ path, err := os.MkdirTemp(dir, prefix) + + if err != nil { + t.Fatalf("Error when creating directory %s with prefix %s: %s", dir, prefix, err) +@@ -30,7 +29,7 @@ func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) { + // When an error occurs, it terminates the test + func createTestTempFile(t *testing.T, dir, filename, contents string, perm os.FileMode) string { + filePath := filepath.Join(dir, filename) +- err := ioutil.WriteFile(filePath, []byte(contents), perm) ++ err := os.WriteFile(filePath, []byte(contents), perm) + + if err != nil { + t.Fatalf("Error when creating %s file: %s", filename, err) +diff --git a/builder/remotecontext/detect_test.go b/builder/remotecontext/detect_test.go +index 04b7686c7a..71dfd7bbb9 100644 +--- a/builder/remotecontext/detect_test.go ++++ b/builder/remotecontext/detect_test.go +@@ -2,7 +2,6 @@ package remotecontext // import "github.com/docker/docker/builder/remotecontext" + + import ( + "errors" +- "io/ioutil" + "log" + "os" + "sort" +@@ -20,7 +19,7 @@ const ( + + const shouldStayFilename = "should_stay" + +-func extractFilenames(files []os.FileInfo) []string { ++func extractFilenames(files []os.DirEntry) []string { + filenames := make([]string, len(files)) + + for i, file := range files { +@@ -31,7 +30,7 @@ func extractFilenames(files []os.FileInfo) []string { + } + + func checkDirectory(t *testing.T, dir string, expectedFiles []string) { +- files, err := ioutil.ReadDir(dir) ++ files, err := os.ReadDir(dir) + + if err != nil { + t.Fatalf("Could not read directory: %s", err) +diff --git a/builder/remotecontext/git/gitutils.go b/builder/remotecontext/git/gitutils.go +index 1037ef5821..c20f8da75b 100644 +--- a/builder/remotecontext/git/gitutils.go ++++ b/builder/remotecontext/git/gitutils.go +@@ -1,7 +1,6 @@ + package git // import "github.com/docker/docker/builder/remotecontext/git" + + import ( +- "io/ioutil" + "net/http" + "net/url" + "os" +@@ -51,7 +50,7 @@ func Clone(remoteURL string, opts ...CloneOption) (string, error) { + func (repo gitRepo) clone() (checkoutDir string, err error) { + fetch := fetchArgs(repo.remote, repo.ref) + +- root, err := ioutil.TempDir("", "docker-build-git") ++ root, err := os.MkdirTemp("", "docker-build-git") + if err != nil { + return "", err + } +diff --git a/builder/remotecontext/remote.go b/builder/remotecontext/remote.go +index 8047494c9d..6eeadf521d 100644 +--- a/builder/remotecontext/remote.go ++++ b/builder/remotecontext/remote.go +@@ -4,7 +4,6 @@ import ( + "bytes" + "fmt" + "io" +- "io/ioutil" + "net" + "net/http" + "net/url" +@@ -58,7 +57,7 @@ func GetWithStatusError(address string) (resp *http.Response, err error) { + return resp, nil + } + msg := fmt.Sprintf("failed to GET %s with status %s", address, resp.Status) +- body, err := ioutil.ReadAll(resp.Body) ++ body, err := io.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + return nil, errdefs.System(errors.New(msg + ": error reading body")) +diff --git a/builder/remotecontext/remote_test.go b/builder/remotecontext/remote_test.go +index 8e1768c894..a945181183 100644 +--- a/builder/remotecontext/remote_test.go ++++ b/builder/remotecontext/remote_test.go +@@ -3,7 +3,6 @@ package remotecontext // import "github.com/docker/docker/builder/remotecontext" + import ( + "bytes" + "io" +- "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" +@@ -52,7 +51,7 @@ func TestSelectAcceptableMIME(t *testing.T) { + + func TestInspectEmptyResponse(t *testing.T) { + ct := "application/octet-stream" +- br := ioutil.NopCloser(bytes.NewReader([]byte(""))) ++ br := io.NopCloser(bytes.NewReader([]byte(""))) + contentType, bReader, err := inspectResponse(ct, br, 0) + if err == nil { + t.Fatal("Should have generated an error for an empty response") +@@ -60,7 +59,7 @@ func TestInspectEmptyResponse(t *testing.T) { + if contentType != "application/octet-stream" { + t.Fatalf("Content type should be 'application/octet-stream' but is %q", contentType) + } +- body, err := ioutil.ReadAll(bReader) ++ body, err := io.ReadAll(bReader) + if err != nil { + t.Fatal(err) + } +@@ -71,7 +70,7 @@ func TestInspectEmptyResponse(t *testing.T) { + + func TestInspectResponseBinary(t *testing.T) { + ct := "application/octet-stream" +- br := ioutil.NopCloser(bytes.NewReader(binaryContext)) ++ br := io.NopCloser(bytes.NewReader(binaryContext)) + contentType, bReader, err := inspectResponse(ct, br, int64(len(binaryContext))) + if err != nil { + t.Fatal(err) +@@ -79,7 +78,7 @@ func TestInspectResponseBinary(t *testing.T) { + if contentType != "application/octet-stream" { + t.Fatalf("Content type should be 'application/octet-stream' but is %q", contentType) + } +- body, err := ioutil.ReadAll(bReader) ++ body, err := io.ReadAll(bReader) + if err != nil { + t.Fatal(err) + } +@@ -96,7 +95,7 @@ func TestInspectResponseBinary(t *testing.T) { + func TestResponseUnsupportedContentType(t *testing.T) { + content := []byte(dockerfileContents) + ct := "application/json" +- br := ioutil.NopCloser(bytes.NewReader(content)) ++ br := io.NopCloser(bytes.NewReader(content)) + contentType, bReader, err := inspectResponse(ct, br, int64(len(dockerfileContents))) + + if err == nil { +@@ -105,7 +104,7 @@ func TestResponseUnsupportedContentType(t *testing.T) { + if contentType != ct { + t.Fatalf("Should not have altered content-type: orig: %s, altered: %s", ct, contentType) + } +- body, err := ioutil.ReadAll(bReader) ++ body, err := io.ReadAll(bReader) + if err != nil { + t.Fatal(err) + } +@@ -117,7 +116,7 @@ func TestResponseUnsupportedContentType(t *testing.T) { + func TestInspectResponseTextSimple(t *testing.T) { + content := []byte(dockerfileContents) + ct := "text/plain" +- br := ioutil.NopCloser(bytes.NewReader(content)) ++ br := io.NopCloser(bytes.NewReader(content)) + contentType, bReader, err := inspectResponse(ct, br, int64(len(content))) + if err != nil { + t.Fatal(err) +@@ -125,7 +124,7 @@ func TestInspectResponseTextSimple(t *testing.T) { + if contentType != "text/plain" { + t.Fatalf("Content type should be 'text/plain' but is %q", contentType) + } +- body, err := ioutil.ReadAll(bReader) ++ body, err := io.ReadAll(bReader) + if err != nil { + t.Fatal(err) + } +@@ -136,7 +135,7 @@ func TestInspectResponseTextSimple(t *testing.T) { + + func TestInspectResponseEmptyContentType(t *testing.T) { + content := []byte(dockerfileContents) +- br := ioutil.NopCloser(bytes.NewReader(content)) ++ br := io.NopCloser(bytes.NewReader(content)) + contentType, bodyReader, err := inspectResponse("", br, int64(len(content))) + if err != nil { + t.Fatal(err) +@@ -144,7 +143,7 @@ func TestInspectResponseEmptyContentType(t *testing.T) { + if contentType != "text/plain" { + t.Fatalf("Content type should be 'text/plain' but is %q", contentType) + } +- body, err := ioutil.ReadAll(bodyReader) ++ body, err := io.ReadAll(bodyReader) + if err != nil { + t.Fatal(err) + } +@@ -156,7 +155,7 @@ func TestInspectResponseEmptyContentType(t *testing.T) { + func TestUnknownContentLength(t *testing.T) { + content := []byte(dockerfileContents) + ct := "text/plain" +- br := ioutil.NopCloser(bytes.NewReader(content)) ++ br := io.NopCloser(bytes.NewReader(content)) + contentType, bReader, err := inspectResponse(ct, br, -1) + if err != nil { + t.Fatal(err) +@@ -164,7 +163,7 @@ func TestUnknownContentLength(t *testing.T) { + if contentType != "text/plain" { + t.Fatalf("Content type should be 'text/plain' but is %q", contentType) + } +- body, err := ioutil.ReadAll(bReader) ++ body, err := io.ReadAll(bReader) + if err != nil { + t.Fatal(err) + } +@@ -191,7 +190,7 @@ func TestDownloadRemote(t *testing.T) { + assert.NilError(t, err) + + assert.Check(t, is.Equal(mimeTypes.TextPlain, contentType)) +- raw, err := ioutil.ReadAll(content) ++ raw, err := io.ReadAll(content) + assert.NilError(t, err) + assert.Check(t, is.Equal(dockerfileContents, string(raw))) + } +@@ -238,5 +237,5 @@ func TestGetWithStatusError(t *testing.T) { + + func readBody(b io.ReadCloser) ([]byte, error) { + defer b.Close() +- return ioutil.ReadAll(b) ++ return io.ReadAll(b) + } +diff --git a/builder/remotecontext/tarsum_test.go b/builder/remotecontext/tarsum_test.go +index c6a417d7fd..fd5d9edc2f 100644 +--- a/builder/remotecontext/tarsum_test.go ++++ b/builder/remotecontext/tarsum_test.go +@@ -1,7 +1,6 @@ + package remotecontext // import "github.com/docker/docker/builder/remotecontext" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -23,7 +22,7 @@ func init() { + } + + func TestCloseRootDirectory(t *testing.T) { +- contextDir, err := ioutil.TempDir("", "builder-tarsum-test") ++ contextDir, err := os.MkdirTemp("", "builder-tarsum-test") + defer os.RemoveAll(contextDir) + if err != nil { + t.Fatalf("Error with creating temporary directory: %s", err) +diff --git a/builder/remotecontext/utils_test.go b/builder/remotecontext/utils_test.go +index 6a4c707a6e..9a44719f8a 100644 +--- a/builder/remotecontext/utils_test.go ++++ b/builder/remotecontext/utils_test.go +@@ -1,7 +1,6 @@ + package remotecontext // import "github.com/docker/docker/builder/remotecontext" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -11,7 +10,7 @@ import ( + // It returns the created path and a cleanup function which is meant to be used as deferred call. + // When an error occurs, it terminates the test. + func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) { +- path, err := ioutil.TempDir(dir, prefix) ++ path, err := os.MkdirTemp(dir, prefix) + + if err != nil { + t.Fatalf("Error when creating directory %s with prefix %s: %s", dir, prefix, err) +@@ -32,7 +31,7 @@ func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) { + // whose parent directories are properly cleaned up. + // When an error occurs, it terminates the test. + func createTestTempSubdir(t *testing.T, dir, prefix string) string { +- path, err := ioutil.TempDir(dir, prefix) ++ path, err := os.MkdirTemp(dir, prefix) + + if err != nil { + t.Fatalf("Error when creating directory %s with prefix %s: %s", dir, prefix, err) +@@ -45,7 +44,7 @@ func createTestTempSubdir(t *testing.T, dir, prefix string) string { + // When an error occurs, it terminates the test + func createTestTempFile(t *testing.T, dir, filename, contents string, perm os.FileMode) string { + filePath := filepath.Join(dir, filename) +- err := ioutil.WriteFile(filePath, []byte(contents), perm) ++ err := os.WriteFile(filePath, []byte(contents), perm) + + if err != nil { + t.Fatalf("Error when creating %s file: %s", filename, err) +diff --git a/client/checkpoint_create_test.go b/client/checkpoint_create_test.go +index 2d48ece150..cd2f544307 100644 +--- a/client/checkpoint_create_test.go ++++ b/client/checkpoint_create_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -58,7 +58,7 @@ func TestCheckpointCreate(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/checkpoint_delete_test.go b/client/checkpoint_delete_test.go +index 71c261bc2d..f132e52b6d 100644 +--- a/client/checkpoint_delete_test.go ++++ b/client/checkpoint_delete_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -40,7 +40,7 @@ func TestCheckpointDelete(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/checkpoint_list_test.go b/client/checkpoint_list_test.go +index f444a192ca..673956340f 100644 +--- a/client/checkpoint_list_test.go ++++ b/client/checkpoint_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -43,7 +43,7 @@ func TestCheckpointList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/client_mock_test.go b/client/client_mock_test.go +index 390a1eed7d..c119e59bbb 100644 +--- a/client/client_mock_test.go ++++ b/client/client_mock_test.go +@@ -3,7 +3,7 @@ package client // import "github.com/docker/docker/client" + import ( + "bytes" + "encoding/json" +- "io/ioutil" ++ "io" + "net/http" + + "github.com/docker/docker/api/types" +@@ -37,7 +37,7 @@ func errorMock(statusCode int, message string) func(req *http.Request) (*http.Re + + return &http.Response{ + StatusCode: statusCode, +- Body: ioutil.NopCloser(bytes.NewReader(body)), ++ Body: io.NopCloser(bytes.NewReader(body)), + Header: header, + }, nil + } +@@ -47,7 +47,7 @@ func plainTextErrorMock(statusCode int, message string) func(req *http.Request) + return func(req *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: statusCode, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(message))), ++ Body: io.NopCloser(bytes.NewReader([]byte(message))), + }, nil + } + } +diff --git a/client/client_test.go b/client/client_test.go +index 5fd819fd1c..14739f2ca9 100644 +--- a/client/client_test.go ++++ b/client/client_test.go +@@ -3,7 +3,7 @@ package client // import "github.com/docker/docker/client" + import ( + "bytes" + "context" +- "io/ioutil" ++ "io" + "net/http" + "net/url" + "os" +@@ -274,7 +274,7 @@ func TestNegotiateAPIVersionAutomatic(t *testing.T) { + httpClient := newMockClient(func(req *http.Request) (*http.Response, error) { + resp := &http.Response{StatusCode: http.StatusOK, Header: http.Header{}} + resp.Header.Set("API-Version", pingVersion) +- resp.Body = ioutil.NopCloser(strings.NewReader("OK")) ++ resp.Body = io.NopCloser(strings.NewReader("OK")) + return resp, nil + }) + +diff --git a/client/config_create_test.go b/client/config_create_test.go +index 24ad5bbf3c..18b18b5401 100644 +--- a/client/config_create_test.go ++++ b/client/config_create_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -56,7 +56,7 @@ func TestConfigCreate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusCreated, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/config_inspect.go b/client/config_inspect.go +index 7d0ce3e11c..f1b0d7f753 100644 +--- a/client/config_inspect.go ++++ b/client/config_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + + "github.com/docker/docker/api/types/swarm" + ) +@@ -23,7 +23,7 @@ func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.C + return swarm.Config{}, nil, wrapResponseError(err, resp, "config", id) + } + +- body, err := ioutil.ReadAll(resp.body) ++ body, err := io.ReadAll(resp.body) + if err != nil { + return swarm.Config{}, nil, err + } +diff --git a/client/config_inspect_test.go b/client/config_inspect_test.go +index d0b9c1dc7c..139d6022cc 100644 +--- a/client/config_inspect_test.go ++++ b/client/config_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -89,7 +89,7 @@ func TestConfigInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/config_list_test.go b/client/config_list_test.go +index 4799cebb61..9c4cf6642b 100644 +--- a/client/config_list_test.go ++++ b/client/config_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -92,7 +92,7 @@ func TestConfigList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/config_remove_test.go b/client/config_remove_test.go +index 8b97db46cb..1573f318ae 100644 +--- a/client/config_remove_test.go ++++ b/client/config_remove_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -49,7 +49,7 @@ func TestConfigRemove(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/client/config_update_test.go b/client/config_update_test.go +index 5f1a532541..7b6d15be87 100644 +--- a/client/config_update_test.go ++++ b/client/config_update_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -50,7 +50,7 @@ func TestConfigUpdate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/client/container_commit_test.go b/client/container_commit_test.go +index e9cc9cbf9d..80aca7bbb3 100644 +--- a/client/container_commit_test.go ++++ b/client/container_commit_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -76,7 +76,7 @@ func TestContainerCommit(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/container_copy_test.go b/client/container_copy_test.go +index 1d737cb7e2..c94aa5e1aa 100644 +--- a/client/container_copy_test.go ++++ b/client/container_copy_test.go +@@ -6,7 +6,7 @@ import ( + "encoding/base64" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -40,7 +40,7 @@ func TestContainerStatPathNoHeaderError(t *testing.T) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +@@ -76,7 +76,7 @@ func TestContainerStatPath(t *testing.T) { + base64PathStat := base64.StdEncoding.EncodeToString(content) + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + Header: http.Header{ + "X-Docker-Container-Path-Stat": []string{base64PathStat}, + }, +@@ -147,7 +147,7 @@ func TestCopyToContainer(t *testing.T) { + return nil, fmt.Errorf("noOverwriteDirNonDir not set in URL query properly, expected true, got %s", noOverwriteDirNonDir) + } + +- content, err := ioutil.ReadAll(req.Body) ++ content, err := io.ReadAll(req.Body) + if err != nil { + return nil, err + } +@@ -160,7 +160,7 @@ func TestCopyToContainer(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +@@ -208,7 +208,7 @@ func TestCopyFromContainerNoHeaderError(t *testing.T) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +@@ -246,7 +246,7 @@ func TestCopyFromContainer(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("content"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("content"))), + Header: http.Header{ + "X-Docker-Container-Path-Stat": []string{base64PathStat}, + }, +@@ -263,7 +263,7 @@ func TestCopyFromContainer(t *testing.T) { + if stat.Mode != 0700 { + t.Fatalf("expected container path stat mode to be 0700, got '%v'", stat.Mode) + } +- content, err := ioutil.ReadAll(r) ++ content, err := io.ReadAll(r) + if err != nil { + t.Fatal(err) + } +diff --git a/client/container_create_test.go b/client/container_create_test.go +index 7b12df6090..2a8c5eef2b 100644 +--- a/client/container_create_test.go ++++ b/client/container_create_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -62,7 +62,7 @@ func TestContainerCreateWithName(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +@@ -97,7 +97,7 @@ func TestContainerCreateAutoRemove(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + } + } +diff --git a/client/container_diff_test.go b/client/container_diff_test.go +index 002267a362..14e243343e 100644 +--- a/client/container_diff_test.go ++++ b/client/container_diff_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -46,7 +46,7 @@ func TestContainerDiff(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/container_exec_test.go b/client/container_exec_test.go +index c4a19bd126..3daae491d8 100644 +--- a/client/container_exec_test.go ++++ b/client/container_exec_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -53,7 +53,7 @@ func TestContainerExecCreate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +@@ -99,7 +99,7 @@ func TestContainerExecStart(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +@@ -139,7 +139,7 @@ func TestContainerExecInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/container_export_test.go b/client/container_export_test.go +index e72a97a0b2..1a19aebd93 100644 +--- a/client/container_export_test.go ++++ b/client/container_export_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -32,7 +32,7 @@ func TestContainerExport(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("response"))), + }, nil + }), + } +@@ -41,7 +41,7 @@ func TestContainerExport(t *testing.T) { + t.Fatal(err) + } + defer body.Close() +- content, err := ioutil.ReadAll(body) ++ content, err := io.ReadAll(body) + if err != nil { + t.Fatal(err) + } +diff --git a/client/container_inspect.go b/client/container_inspect.go +index c496bcffea..43db32bd97 100644 +--- a/client/container_inspect.go ++++ b/client/container_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + "net/url" + + "github.com/docker/docker/api/types" +@@ -41,7 +41,7 @@ func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID stri + return types.ContainerJSON{}, nil, wrapResponseError(err, serverResp, "container", containerID) + } + +- body, err := ioutil.ReadAll(serverResp.body) ++ body, err := io.ReadAll(serverResp.body) + if err != nil { + return types.ContainerJSON{}, nil, err + } +diff --git a/client/container_inspect_test.go b/client/container_inspect_test.go +index 82960a3dcc..54c70d0304 100644 +--- a/client/container_inspect_test.go ++++ b/client/container_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -68,7 +68,7 @@ func TestContainerInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +@@ -110,7 +110,7 @@ func TestContainerInspectNode(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/container_kill_test.go b/client/container_kill_test.go +index fcfe8e5153..6db886d2c5 100644 +--- a/client/container_kill_test.go ++++ b/client/container_kill_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -35,7 +35,7 @@ func TestContainerKill(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/container_list_test.go b/client/container_list_test.go +index f734e78f14..dfd3494ca6 100644 +--- a/client/container_list_test.go ++++ b/client/container_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -73,7 +73,7 @@ func TestContainerList(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/container_logs_test.go b/client/container_logs_test.go +index 970e69c1a8..07c3bbd137 100644 +--- a/client/container_logs_test.go ++++ b/client/container_logs_test.go +@@ -5,7 +5,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "log" + "net/http" + "os" +@@ -135,7 +134,7 @@ func TestContainerLogs(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("response"))), + }, nil + }), + } +@@ -146,7 +145,7 @@ func TestContainerLogs(t *testing.T) { + } + assert.NilError(t, err) + defer body.Close() +- content, err := ioutil.ReadAll(body) ++ content, err := io.ReadAll(body) + assert.NilError(t, err) + assert.Check(t, is.Contains(string(content), "response")) + } +diff --git a/client/container_pause_test.go b/client/container_pause_test.go +index 81ada2f3ee..45cbe21498 100644 +--- a/client/container_pause_test.go ++++ b/client/container_pause_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -31,7 +31,7 @@ func TestContainerPause(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/container_prune_test.go b/client/container_prune_test.go +index 6d1060cf52..9525efc3bc 100644 +--- a/client/container_prune_test.go ++++ b/client/container_prune_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -114,7 +114,7 @@ func TestContainersPrune(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + version: "1.25", +diff --git a/client/container_remove_test.go b/client/container_remove_test.go +index c0504bb8b0..ffc15eaf7e 100644 +--- a/client/container_remove_test.go ++++ b/client/container_remove_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -56,7 +56,7 @@ func TestContainerRemove(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/container_rename_test.go b/client/container_rename_test.go +index 5abcd32bdf..5ccc18eb3c 100644 +--- a/client/container_rename_test.go ++++ b/client/container_rename_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -35,7 +35,7 @@ func TestContainerRename(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/container_resize_test.go b/client/container_resize_test.go +index b0aa259a06..0fd63fe3e6 100644 +--- a/client/container_resize_test.go ++++ b/client/container_resize_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -77,7 +77,7 @@ func resizeTransport(expectedURL string) func(req *http.Request) (*http.Response + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + } + } +diff --git a/client/container_restart_test.go b/client/container_restart_test.go +index 29df115b11..085da26b70 100644 +--- a/client/container_restart_test.go ++++ b/client/container_restart_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestContainerRestart(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/container_start_test.go b/client/container_start_test.go +index cb9376b680..07fce72e5d 100644 +--- a/client/container_start_test.go ++++ b/client/container_start_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -46,7 +46,7 @@ func TestContainerStart(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/container_stats_test.go b/client/container_stats_test.go +index b52385296e..933b67ca88 100644 +--- a/client/container_stats_test.go ++++ b/client/container_stats_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -51,7 +51,7 @@ func TestContainerStats(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("response"))), + }, nil + }), + } +@@ -60,7 +60,7 @@ func TestContainerStats(t *testing.T) { + t.Fatal(err) + } + defer resp.Body.Close() +- content, err := ioutil.ReadAll(resp.Body) ++ content, err := io.ReadAll(resp.Body) + if err != nil { + t.Fatal(err) + } +diff --git a/client/container_stop_test.go b/client/container_stop_test.go +index 0bb8c12157..f5df1805cb 100644 +--- a/client/container_stop_test.go ++++ b/client/container_stop_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestContainerStop(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/container_top_test.go b/client/container_top_test.go +index 936888dabf..35d5c42397 100644 +--- a/client/container_top_test.go ++++ b/client/container_top_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "reflect" + "strings" +@@ -57,7 +57,7 @@ func TestContainerTop(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/container_unpause_test.go b/client/container_unpause_test.go +index f53816b714..42eef30fca 100644 +--- a/client/container_unpause_test.go ++++ b/client/container_unpause_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -31,7 +31,7 @@ func TestContainerUnpause(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/container_update_test.go b/client/container_update_test.go +index b7b4423933..83ae098be0 100644 +--- a/client/container_update_test.go ++++ b/client/container_update_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -40,7 +40,7 @@ func TestContainerUpdate(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/container_wait_test.go b/client/container_wait_test.go +index 79d1e16d76..ab42272887 100644 +--- a/client/container_wait_test.go ++++ b/client/container_wait_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "log" + "net/http" + "strings" +@@ -46,7 +46,7 @@ func TestContainerWait(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/disk_usage_test.go b/client/disk_usage_test.go +index 4166e8e2bd..b43e0646c4 100644 +--- a/client/disk_usage_test.go ++++ b/client/disk_usage_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -46,7 +46,7 @@ func TestDiskUsage(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/events_test.go b/client/events_test.go +index 601098fa22..76602a1954 100644 +--- a/client/events_test.go ++++ b/client/events_test.go +@@ -6,7 +6,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net/http" + "strings" + "testing" +@@ -138,7 +137,7 @@ func TestEvents(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(buffer), ++ Body: io.NopCloser(buffer), + }, nil + }), + } +diff --git a/client/hijack_test.go b/client/hijack_test.go +index c031155d02..67d3894756 100644 +--- a/client/hijack_test.go ++++ b/client/hijack_test.go +@@ -3,7 +3,7 @@ package client + import ( + "context" + "fmt" +- "io/ioutil" ++ "io" + "net" + "net/http" + "net/http/httptest" +@@ -92,7 +92,7 @@ func TestTLSCloseWriter(t *testing.T) { + _, err = resp.Conn.Write([]byte("hello")) + assert.NilError(t, err) + +- b, err := ioutil.ReadAll(resp.Reader) ++ b, err := io.ReadAll(resp.Reader) + assert.NilError(t, err) + assert.Assert(t, string(b) == "hello") + assert.Assert(t, resp.CloseWrite()) +diff --git a/client/image_build_test.go b/client/image_build_test.go +index 0d4ea85c63..3d6c0a972d 100644 +--- a/client/image_build_test.go ++++ b/client/image_build_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "reflect" + "strings" +@@ -195,7 +195,7 @@ func TestImageBuild(t *testing.T) { + headers.Add("Server", "Docker/v1.23 (MyOS)") + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + Header: headers, + }, nil + }), +@@ -207,7 +207,7 @@ func TestImageBuild(t *testing.T) { + if buildResponse.OSType != "MyOS" { + t.Fatalf("expected OSType to be 'MyOS', got %s", buildResponse.OSType) + } +- response, err := ioutil.ReadAll(buildResponse.Body) ++ response, err := io.ReadAll(buildResponse.Body) + if err != nil { + t.Fatal(err) + } +diff --git a/client/image_create_test.go b/client/image_create_test.go +index d05fd80e11..3095cbc05b 100644 +--- a/client/image_create_test.go ++++ b/client/image_create_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -52,7 +52,7 @@ func TestImageCreate(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +@@ -63,7 +63,7 @@ func TestImageCreate(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- response, err := ioutil.ReadAll(createResponse) ++ response, err := io.ReadAll(createResponse) + if err != nil { + t.Fatal(err) + } +diff --git a/client/image_history_test.go b/client/image_history_test.go +index 286561f943..bb4a2b11fc 100644 +--- a/client/image_history_test.go ++++ b/client/image_history_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -47,7 +47,7 @@ func TestImageHistory(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/image_import_test.go b/client/image_import_test.go +index 7827bddab8..34f1e0642f 100644 +--- a/client/image_import_test.go ++++ b/client/image_import_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "reflect" + "strings" +@@ -56,7 +56,7 @@ func TestImageImport(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("response"))), + }, nil + }), + } +@@ -71,7 +71,7 @@ func TestImageImport(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- response, err := ioutil.ReadAll(importResponse) ++ response, err := io.ReadAll(importResponse) + if err != nil { + t.Fatal(err) + } +diff --git a/client/image_inspect.go b/client/image_inspect.go +index 1eb8dce025..03aa12d8b4 100644 +--- a/client/image_inspect.go ++++ b/client/image_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + + "github.com/docker/docker/api/types" + ) +@@ -20,7 +20,7 @@ func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (typ + return types.ImageInspect{}, nil, wrapResponseError(err, serverResp, "image", imageID) + } + +- body, err := ioutil.ReadAll(serverResp.body) ++ body, err := io.ReadAll(serverResp.body) + if err != nil { + return types.ImageInspect{}, nil, err + } +diff --git a/client/image_inspect_test.go b/client/image_inspect_test.go +index bbaaa19010..893552a2e4 100644 +--- a/client/image_inspect_test.go ++++ b/client/image_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "reflect" + "strings" +@@ -67,7 +67,7 @@ func TestImageInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/image_list_test.go b/client/image_list_test.go +index b1182b9bc6..4619393ff3 100644 +--- a/client/image_list_test.go ++++ b/client/image_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -96,7 +96,7 @@ func TestImageList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +@@ -137,7 +137,7 @@ func TestImageListApiBefore125(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + version: "1.24", +diff --git a/client/image_load_test.go b/client/image_load_test.go +index bdfd0f047f..4e53cb83a3 100644 +--- a/client/image_load_test.go ++++ b/client/image_load_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -71,7 +71,7 @@ func TestImageLoad(t *testing.T) { + headers.Add("Content-Type", loadCase.responseContentType) + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(expectedOutput))), ++ Body: io.NopCloser(bytes.NewReader([]byte(expectedOutput))), + Header: headers, + }, nil + }), +@@ -85,7 +85,7 @@ func TestImageLoad(t *testing.T) { + if imageLoadResponse.JSON != loadCase.expectedResponseJSON { + t.Fatalf("expected a JSON response, was not.") + } +- body, err := ioutil.ReadAll(imageLoadResponse.Body) ++ body, err := io.ReadAll(imageLoadResponse.Body) + if err != nil { + t.Fatal(err) + } +diff --git a/client/image_prune_test.go b/client/image_prune_test.go +index f5f61a8d3c..a3652a1003 100644 +--- a/client/image_prune_test.go ++++ b/client/image_prune_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -108,7 +108,7 @@ func TestImagesPrune(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + version: "1.25", +diff --git a/client/image_pull_test.go b/client/image_pull_test.go +index 03720ed456..92793e1e39 100644 +--- a/client/image_pull_test.go ++++ b/client/image_pull_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -87,7 +87,7 @@ func TestImagePullWithPrivilegedFuncNoError(t *testing.T) { + if auth == "NotValid" { + return &http.Response{ + StatusCode: http.StatusUnauthorized, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("Invalid credentials"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("Invalid credentials"))), + }, nil + } + if auth != "IAmValid" { +@@ -104,7 +104,7 @@ func TestImagePullWithPrivilegedFuncNoError(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("hello world"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("hello world"))), + }, nil + }), + } +@@ -118,7 +118,7 @@ func TestImagePullWithPrivilegedFuncNoError(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- body, err := ioutil.ReadAll(resp) ++ body, err := io.ReadAll(resp) + if err != nil { + t.Fatal(err) + } +@@ -178,7 +178,7 @@ func TestImagePullWithoutErrors(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(expectedOutput))), ++ Body: io.NopCloser(bytes.NewReader([]byte(expectedOutput))), + }, nil + }), + } +@@ -188,7 +188,7 @@ func TestImagePullWithoutErrors(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- body, err := ioutil.ReadAll(resp) ++ body, err := io.ReadAll(resp) + if err != nil { + t.Fatal(err) + } +diff --git a/client/image_push_test.go b/client/image_push_test.go +index a690b8f28e..9b161717ca 100644 +--- a/client/image_push_test.go ++++ b/client/image_push_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -92,7 +92,7 @@ func TestImagePushWithPrivilegedFuncNoError(t *testing.T) { + if auth == "NotValid" { + return &http.Response{ + StatusCode: http.StatusUnauthorized, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("Invalid credentials"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("Invalid credentials"))), + }, nil + } + if auth != "IAmValid" { +@@ -105,7 +105,7 @@ func TestImagePushWithPrivilegedFuncNoError(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("hello world"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("hello world"))), + }, nil + }), + } +@@ -119,7 +119,7 @@ func TestImagePushWithPrivilegedFuncNoError(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- body, err := ioutil.ReadAll(resp) ++ body, err := io.ReadAll(resp) + if err != nil { + t.Fatal(err) + } +@@ -178,7 +178,7 @@ func TestImagePushWithoutErrors(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(expectedOutput))), ++ Body: io.NopCloser(bytes.NewReader([]byte(expectedOutput))), + }, nil + }), + } +@@ -188,7 +188,7 @@ func TestImagePushWithoutErrors(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- body, err := ioutil.ReadAll(resp) ++ body, err := io.ReadAll(resp) + if err != nil { + t.Fatal(err) + } +diff --git a/client/image_remove_test.go b/client/image_remove_test.go +index e4e3febe27..919baa2f68 100644 +--- a/client/image_remove_test.go ++++ b/client/image_remove_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -90,7 +90,7 @@ func TestImageRemove(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/image_save_test.go b/client/image_save_test.go +index 7e887f3870..c90a742c4a 100644 +--- a/client/image_save_test.go ++++ b/client/image_save_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "reflect" + "strings" +@@ -39,7 +39,7 @@ func TestImageSave(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("response"))), + }, nil + }), + } +@@ -47,7 +47,7 @@ func TestImageSave(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- response, err := ioutil.ReadAll(saveResponse) ++ response, err := io.ReadAll(saveResponse) + if err != nil { + t.Fatal(err) + } +diff --git a/client/image_search_test.go b/client/image_search_test.go +index 6e3619b5ea..ced6deeb2b 100644 +--- a/client/image_search_test.go ++++ b/client/image_search_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -77,7 +77,7 @@ func TestImageSearchWithPrivilegedFuncNoError(t *testing.T) { + if auth == "NotValid" { + return &http.Response{ + StatusCode: http.StatusUnauthorized, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("Invalid credentials"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("Invalid credentials"))), + }, nil + } + if auth != "IAmValid" { +@@ -98,7 +98,7 @@ func TestImageSearchWithPrivilegedFuncNoError(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +@@ -149,7 +149,7 @@ func TestImageSearchWithoutErrors(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/image_tag_test.go b/client/image_tag_test.go +index 2e820efcf6..63653af207 100644 +--- a/client/image_tag_test.go ++++ b/client/image_tag_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -132,7 +132,7 @@ func TestImageTag(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/info_test.go b/client/info_test.go +index cbaad6e259..f1d5383738 100644 +--- a/client/info_test.go ++++ b/client/info_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -29,7 +29,7 @@ func TestInfoInvalidResponseJSONError(t *testing.T) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("invalid json"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("invalid json"))), + }, nil + }), + } +@@ -57,7 +57,7 @@ func TestInfo(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/network_connect_test.go b/client/network_connect_test.go +index 75141b6a22..30f2f254d6 100644 +--- a/client/network_connect_test.go ++++ b/client/network_connect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -54,7 +54,7 @@ func TestNetworkConnectEmptyNilEndpointSettings(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +@@ -97,7 +97,7 @@ func TestNetworkConnect(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/network_create_test.go b/client/network_create_test.go +index a6bb29bee6..72969864b7 100644 +--- a/client/network_create_test.go ++++ b/client/network_create_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -47,7 +47,7 @@ func TestNetworkCreate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/network_disconnect_test.go b/client/network_disconnect_test.go +index 19fec8b31b..5a44bcd8e0 100644 +--- a/client/network_disconnect_test.go ++++ b/client/network_disconnect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -53,7 +53,7 @@ func TestNetworkDisconnect(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/network_inspect.go b/client/network_inspect.go +index 89a05b3021..ecf20ceb6e 100644 +--- a/client/network_inspect.go ++++ b/client/network_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + "net/url" + + "github.com/docker/docker/api/types" +@@ -39,7 +39,7 @@ func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string, + return networkResource, nil, wrapResponseError(err, resp, "network", networkID) + } + +- body, err := ioutil.ReadAll(resp.body) ++ body, err := io.ReadAll(resp.body) + if err != nil { + return networkResource, nil, err + } +diff --git a/client/network_inspect_test.go b/client/network_inspect_test.go +index f0352e95ff..0134d58258 100644 +--- a/client/network_inspect_test.go ++++ b/client/network_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -69,7 +69,7 @@ func TestNetworkInspect(t *testing.T) { + if strings.Contains(req.URL.RawQuery, "scope=global") { + return &http.Response{ + StatusCode: http.StatusNotFound, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + } + +@@ -91,7 +91,7 @@ func TestNetworkInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/network_list_test.go b/client/network_list_test.go +index f0b9cc7c46..66e15e1290 100644 +--- a/client/network_list_test.go ++++ b/client/network_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -93,7 +93,7 @@ func TestNetworkList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/network_prune_test.go b/client/network_prune_test.go +index dd09b95fce..d5019efc69 100644 +--- a/client/network_prune_test.go ++++ b/client/network_prune_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -101,7 +101,7 @@ func TestNetworksPrune(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + version: "1.25", +diff --git a/client/network_remove_test.go b/client/network_remove_test.go +index a87e61f5ea..e7dddff86e 100644 +--- a/client/network_remove_test.go ++++ b/client/network_remove_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -36,7 +36,7 @@ func TestNetworkRemove(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/client/node_inspect.go b/client/node_inspect.go +index d296c9fdde..b58db52856 100644 +--- a/client/node_inspect.go ++++ b/client/node_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + + "github.com/docker/docker/api/types/swarm" + ) +@@ -20,7 +20,7 @@ func (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm + return swarm.Node{}, nil, wrapResponseError(err, serverResp, "node", nodeID) + } + +- body, err := ioutil.ReadAll(serverResp.body) ++ body, err := io.ReadAll(serverResp.body) + if err != nil { + return swarm.Node{}, nil, err + } +diff --git a/client/node_inspect_test.go b/client/node_inspect_test.go +index a6306f4921..ae97061a8b 100644 +--- a/client/node_inspect_test.go ++++ b/client/node_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -64,7 +64,7 @@ func TestNodeInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/node_list_test.go b/client/node_list_test.go +index f5295de25f..5851cd1a77 100644 +--- a/client/node_list_test.go ++++ b/client/node_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -79,7 +79,7 @@ func TestNodeList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/node_remove_test.go b/client/node_remove_test.go +index 3c641b7009..37b5964be1 100644 +--- a/client/node_remove_test.go ++++ b/client/node_remove_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -56,7 +56,7 @@ func TestNodeRemove(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/client/node_update_test.go b/client/node_update_test.go +index 864b50b1fb..772c6fbc89 100644 +--- a/client/node_update_test.go ++++ b/client/node_update_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestNodeUpdate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/client/ping_test.go b/client/ping_test.go +index 2cb4b06ef9..ae3a1f986c 100644 +--- a/client/ping_test.go ++++ b/client/ping_test.go +@@ -3,7 +3,7 @@ package client // import "github.com/docker/docker/client" + import ( + "context" + "errors" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -26,7 +26,7 @@ func TestPingFail(t *testing.T) { + resp.Header.Set("API-Version", "awesome") + resp.Header.Set("Docker-Experimental", "true") + } +- resp.Body = ioutil.NopCloser(strings.NewReader("some error with the server")) ++ resp.Body = io.NopCloser(strings.NewReader("some error with the server")) + return resp, nil + }), + } +@@ -52,7 +52,7 @@ func TestPingWithError(t *testing.T) { + resp.Header = http.Header{} + resp.Header.Set("API-Version", "awesome") + resp.Header.Set("Docker-Experimental", "true") +- resp.Body = ioutil.NopCloser(strings.NewReader("some error with the server")) ++ resp.Body = io.NopCloser(strings.NewReader("some error with the server")) + return resp, errors.New("some error") + }), + } +@@ -72,7 +72,7 @@ func TestPingSuccess(t *testing.T) { + resp.Header = http.Header{} + resp.Header.Set("API-Version", "awesome") + resp.Header.Set("Docker-Experimental", "true") +- resp.Body = ioutil.NopCloser(strings.NewReader("OK")) ++ resp.Body = io.NopCloser(strings.NewReader("OK")) + return resp, nil + }), + } +diff --git a/client/plugin_disable_test.go b/client/plugin_disable_test.go +index b7026de8de..f042adc320 100644 +--- a/client/plugin_disable_test.go ++++ b/client/plugin_disable_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestPluginDisable(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/plugin_enable_test.go b/client/plugin_enable_test.go +index 6090cc5cc3..c7f7a1be7b 100644 +--- a/client/plugin_enable_test.go ++++ b/client/plugin_enable_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestPluginEnable(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/plugin_inspect.go b/client/plugin_inspect.go +index 81b89732b0..4a90bec51a 100644 +--- a/client/plugin_inspect.go ++++ b/client/plugin_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + + "github.com/docker/docker/api/types" + ) +@@ -20,7 +20,7 @@ func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*type + return nil, nil, wrapResponseError(err, resp, "plugin", name) + } + +- body, err := ioutil.ReadAll(resp.body) ++ body, err := io.ReadAll(resp.body) + if err != nil { + return nil, nil, err + } +diff --git a/client/plugin_inspect_test.go b/client/plugin_inspect_test.go +index 5914e3c8f1..898d02e543 100644 +--- a/client/plugin_inspect_test.go ++++ b/client/plugin_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -53,7 +53,7 @@ func TestPluginInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/plugin_list_test.go b/client/plugin_list_test.go +index 665af7d9dc..c2643c3663 100644 +--- a/client/plugin_list_test.go ++++ b/client/plugin_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -92,7 +92,7 @@ func TestPluginList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/plugin_push_test.go b/client/plugin_push_test.go +index f7de99b86a..4b5a0e2e30 100644 +--- a/client/plugin_push_test.go ++++ b/client/plugin_push_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -40,7 +40,7 @@ func TestPluginPush(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/plugin_remove_test.go b/client/plugin_remove_test.go +index 38389fa6a1..210a92d73c 100644 +--- a/client/plugin_remove_test.go ++++ b/client/plugin_remove_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestPluginRemove(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/plugin_set_test.go b/client/plugin_set_test.go +index c9d4220874..6b54023988 100644 +--- a/client/plugin_set_test.go ++++ b/client/plugin_set_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -36,7 +36,7 @@ func TestPluginSet(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/request.go b/client/request.go +index 7f54b1dd80..f07a6cade6 100644 +--- a/client/request.go ++++ b/client/request.go +@@ -6,7 +6,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net" + "net/http" + "net/url" +@@ -199,7 +198,7 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error { + R: serverResp.body, + N: int64(bodyMax), + } +- body, err = ioutil.ReadAll(bodyR) ++ body, err = io.ReadAll(bodyR) + if err != nil { + return err + } +@@ -259,7 +258,7 @@ func encodeData(data interface{}) (*bytes.Buffer, error) { + func ensureReaderClosed(response serverResponse) { + if response.body != nil { + // Drain up to 512 bytes and close the body to let the Transport reuse the connection +- io.CopyN(ioutil.Discard, response.body, 512) ++ io.CopyN(io.Discard, response.body, 512) + response.body.Close() + } + } +diff --git a/client/request_test.go b/client/request_test.go +index e07c0ebcab..b93b5460d3 100644 +--- a/client/request_test.go ++++ b/client/request_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "math/rand" + "net/http" + "strings" +@@ -64,7 +64,7 @@ func TestSetHostHeader(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + +@@ -97,7 +97,7 @@ func TestInfiniteError(t *testing.T) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { + resp := &http.Response{StatusCode: http.StatusInternalServerError} + resp.Header = http.Header{} +- resp.Body = ioutil.NopCloser(infinitR) ++ resp.Body = io.NopCloser(infinitR) + return resp, nil + }), + } +diff --git a/client/secret_create_test.go b/client/secret_create_test.go +index a793eaf321..1b30825e20 100644 +--- a/client/secret_create_test.go ++++ b/client/secret_create_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -56,7 +56,7 @@ func TestSecretCreate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusCreated, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/secret_inspect.go b/client/secret_inspect.go +index d093916c9a..c07c9550d4 100644 +--- a/client/secret_inspect.go ++++ b/client/secret_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + + "github.com/docker/docker/api/types/swarm" + ) +@@ -23,7 +23,7 @@ func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.S + return swarm.Secret{}, nil, wrapResponseError(err, resp, "secret", id) + } + +- body, err := ioutil.ReadAll(resp.body) ++ body, err := io.ReadAll(resp.body) + if err != nil { + return swarm.Secret{}, nil, err + } +diff --git a/client/secret_inspect_test.go b/client/secret_inspect_test.go +index ca309d95e3..094a609206 100644 +--- a/client/secret_inspect_test.go ++++ b/client/secret_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -78,7 +78,7 @@ func TestSecretInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/secret_list_test.go b/client/secret_list_test.go +index a5637c6172..df330aa725 100644 +--- a/client/secret_list_test.go ++++ b/client/secret_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -92,7 +92,7 @@ func TestSecretList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/secret_remove_test.go b/client/secret_remove_test.go +index 31e4416331..64057e6d74 100644 +--- a/client/secret_remove_test.go ++++ b/client/secret_remove_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -49,7 +49,7 @@ func TestSecretRemove(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/client/secret_update_test.go b/client/secret_update_test.go +index eca93bcd1f..75ccdc9790 100644 +--- a/client/secret_update_test.go ++++ b/client/secret_update_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -50,7 +50,7 @@ func TestSecretUpdate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/client/service_create_test.go b/client/service_create_test.go +index 9c7fec41b6..af6dd65e7f 100644 +--- a/client/service_create_test.go ++++ b/client/service_create_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -48,7 +48,7 @@ func TestServiceCreate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +@@ -87,7 +87,7 @@ func TestServiceCreateCompatiblePlatforms(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + } else if strings.HasPrefix(req.URL.Path, "/v1.30/distribution/") { + b, err := json.Marshal(registrytypes.DistributionInspect{ +@@ -106,7 +106,7 @@ func TestServiceCreateCompatiblePlatforms(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + } else { + return nil, fmt.Errorf("unexpected URL '%s'", req.URL.Path) +@@ -163,7 +163,7 @@ func TestServiceCreateDigestPinning(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + } else if strings.HasPrefix(req.URL.Path, "/v1.30/distribution/cannotresolve") { + // unresolvable image +@@ -180,7 +180,7 @@ func TestServiceCreateDigestPinning(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + } + return nil, fmt.Errorf("unexpected URL '%s'", req.URL.Path) +diff --git a/client/service_inspect.go b/client/service_inspect.go +index 2801483b80..c5368bab1e 100644 +--- a/client/service_inspect.go ++++ b/client/service_inspect.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/url" + + "github.com/docker/docker/api/types" +@@ -25,7 +25,7 @@ func (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string, + return swarm.Service{}, nil, wrapResponseError(err, serverResp, "service", serviceID) + } + +- body, err := ioutil.ReadAll(serverResp.body) ++ body, err := io.ReadAll(serverResp.body) + if err != nil { + return swarm.Service{}, nil, err + } +diff --git a/client/service_inspect_test.go b/client/service_inspect_test.go +index f2264b15fd..96b337c717 100644 +--- a/client/service_inspect_test.go ++++ b/client/service_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -65,7 +65,7 @@ func TestServiceInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/service_list_test.go b/client/service_list_test.go +index 1ab674d176..4021f810bb 100644 +--- a/client/service_list_test.go ++++ b/client/service_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -79,7 +79,7 @@ func TestServiceList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/service_logs_test.go b/client/service_logs_test.go +index d7ec806159..ee2592c7bc 100644 +--- a/client/service_logs_test.go ++++ b/client/service_logs_test.go +@@ -5,7 +5,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "log" + "net/http" + "os" +@@ -104,7 +103,7 @@ func TestServiceLogs(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("response"))), + }, nil + }), + } +@@ -115,7 +114,7 @@ func TestServiceLogs(t *testing.T) { + } + assert.NilError(t, err) + defer body.Close() +- content, err := ioutil.ReadAll(body) ++ content, err := io.ReadAll(body) + assert.NilError(t, err) + assert.Check(t, is.Contains(string(content), "response")) + } +diff --git a/client/service_remove_test.go b/client/service_remove_test.go +index ad99b57c28..a6d6f37cb4 100644 +--- a/client/service_remove_test.go ++++ b/client/service_remove_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -48,7 +48,7 @@ func TestServiceRemove(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/client/service_update_test.go b/client/service_update_test.go +index f8a25b5d6a..b1801bf0b6 100644 +--- a/client/service_update_test.go ++++ b/client/service_update_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -64,7 +64,7 @@ func TestServiceUpdate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("{}"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("{}"))), + }, nil + }), + } +diff --git a/client/swarm_get_unlock_key_test.go b/client/swarm_get_unlock_key_test.go +index 2206aad648..3bfbcde529 100644 +--- a/client/swarm_get_unlock_key_test.go ++++ b/client/swarm_get_unlock_key_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -51,7 +51,7 @@ func TestSwarmGetUnlockKey(t *testing.T) { + + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(b)), ++ Body: io.NopCloser(bytes.NewReader(b)), + }, nil + }), + } +diff --git a/client/swarm_init_test.go b/client/swarm_init_test.go +index d929af7d86..3579af3e81 100644 +--- a/client/swarm_init_test.go ++++ b/client/swarm_init_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestSwarmInit(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(`"body"`))), ++ Body: io.NopCloser(bytes.NewReader([]byte(`"body"`))), + }, nil + }), + } +diff --git a/client/swarm_inspect_test.go b/client/swarm_inspect_test.go +index 91a6a7395b..4c56b34fcc 100644 +--- a/client/swarm_inspect_test.go ++++ b/client/swarm_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -42,7 +42,7 @@ func TestSwarmInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/swarm_join_test.go b/client/swarm_join_test.go +index e22c852d8f..933ad9380e 100644 +--- a/client/swarm_join_test.go ++++ b/client/swarm_join_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestSwarmJoin(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/swarm_leave_test.go b/client/swarm_leave_test.go +index 0417381ff6..89fcac8cf8 100644 +--- a/client/swarm_leave_test.go ++++ b/client/swarm_leave_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -54,7 +54,7 @@ func TestSwarmLeave(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/swarm_unlock_test.go b/client/swarm_unlock_test.go +index 2d41bbb451..b308c9052d 100644 +--- a/client/swarm_unlock_test.go ++++ b/client/swarm_unlock_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestSwarmUnlock(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/swarm_update_test.go b/client/swarm_update_test.go +index 5076f6f0c1..66fc6b4e28 100644 +--- a/client/swarm_update_test.go ++++ b/client/swarm_update_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -37,7 +37,7 @@ func TestSwarmUpdate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), ++ Body: io.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }), + } +diff --git a/client/task_inspect.go b/client/task_inspect.go +index 44d40ba5ae..fb0949da5b 100644 +--- a/client/task_inspect.go ++++ b/client/task_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + + "github.com/docker/docker/api/types/swarm" + ) +@@ -20,7 +20,7 @@ func (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm + return swarm.Task{}, nil, wrapResponseError(err, serverResp, "task", taskID) + } + +- body, err := ioutil.ReadAll(serverResp.body) ++ body, err := io.ReadAll(serverResp.body) + if err != nil { + return swarm.Task{}, nil, err + } +diff --git a/client/task_inspect_test.go b/client/task_inspect_test.go +index 3252e16267..f8ed67cf19 100644 +--- a/client/task_inspect_test.go ++++ b/client/task_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -53,7 +53,7 @@ func TestTaskInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/task_list_test.go b/client/task_list_test.go +index 0116f735b4..939319fffd 100644 +--- a/client/task_list_test.go ++++ b/client/task_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -79,7 +79,7 @@ func TestTaskList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/volume_create_test.go b/client/volume_create_test.go +index f782362406..9f8624a292 100644 +--- a/client/volume_create_test.go ++++ b/client/volume_create_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -49,7 +49,7 @@ func TestVolumeCreate(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/volume_inspect.go b/client/volume_inspect.go +index e20b2c67c7..5c5b3f905c 100644 +--- a/client/volume_inspect.go ++++ b/client/volume_inspect.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "io" + + "github.com/docker/docker/api/types" + ) +@@ -28,7 +28,7 @@ func (cli *Client) VolumeInspectWithRaw(ctx context.Context, volumeID string) (t + return volume, nil, wrapResponseError(err, resp, "volume", volumeID) + } + +- body, err := ioutil.ReadAll(resp.body) ++ body, err := io.ReadAll(resp.body) + if err != nil { + return volume, nil, err + } +diff --git a/client/volume_inspect_test.go b/client/volume_inspect_test.go +index 9594caf032..1aa2a54448 100644 +--- a/client/volume_inspect_test.go ++++ b/client/volume_inspect_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -71,7 +71,7 @@ func TestVolumeInspect(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/volume_list_test.go b/client/volume_list_test.go +index ccfb845b47..d26bb51405 100644 +--- a/client/volume_list_test.go ++++ b/client/volume_list_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -83,7 +83,7 @@ func TestVolumeList(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader(content)), ++ Body: io.NopCloser(bytes.NewReader(content)), + }, nil + }), + } +diff --git a/client/volume_remove_test.go b/client/volume_remove_test.go +index ccc4fcd45d..7581f72e8f 100644 +--- a/client/volume_remove_test.go ++++ b/client/volume_remove_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "strings" + "testing" +@@ -36,7 +36,7 @@ func TestVolumeRemove(t *testing.T) { + } + return &http.Response{ + StatusCode: http.StatusOK, +- Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))), ++ Body: io.NopCloser(bytes.NewReader([]byte("body"))), + }, nil + }), + } +diff --git a/cmd/dockerd/service_windows.go b/cmd/dockerd/service_windows.go +index 2d7c3b7da6..e41906c17f 100644 +--- a/cmd/dockerd/service_windows.go ++++ b/cmd/dockerd/service_windows.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "errors" + "fmt" +- "io/ioutil" ++ "io" + "log" + "os" + "os/exec" +@@ -293,7 +293,7 @@ func initService(daemonCli *DaemonCli) (bool, bool, error) { + } + + logrus.AddHook(&etwHook{log}) +- logrus.SetOutput(ioutil.Discard) ++ logrus.SetOutput(io.Discard) + + service = h + go func() { +diff --git a/container/container_unit_test.go b/container/container_unit_test.go +index 1314f37f43..901d56d057 100644 +--- a/container/container_unit_test.go ++++ b/container/container_unit_test.go +@@ -2,7 +2,6 @@ package container // import "github.com/docker/docker/container" + + import ( + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -73,7 +72,7 @@ func TestContainerSecretReferenceDestTarget(t *testing.T) { + } + + func TestContainerLogPathSetForJSONFileLogger(t *testing.T) { +- containerRoot, err := ioutil.TempDir("", "TestContainerLogPathSetForJSONFileLogger") ++ containerRoot, err := os.MkdirTemp("", "TestContainerLogPathSetForJSONFileLogger") + assert.NilError(t, err) + defer os.RemoveAll(containerRoot) + +@@ -98,7 +97,7 @@ func TestContainerLogPathSetForJSONFileLogger(t *testing.T) { + } + + func TestContainerLogPathSetForRingLogger(t *testing.T) { +- containerRoot, err := ioutil.TempDir("", "TestContainerLogPathSetForRingLogger") ++ containerRoot, err := os.MkdirTemp("", "TestContainerLogPathSetForRingLogger") + assert.NilError(t, err) + defer os.RemoveAll(containerRoot) + +diff --git a/container/container_unix.go b/container/container_unix.go +index 1a6c08c214..486557f482 100644 +--- a/container/container_unix.go ++++ b/container/container_unix.go +@@ -4,7 +4,6 @@ + package container // import "github.com/docker/docker/container" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "syscall" +@@ -58,7 +57,7 @@ func (container *Container) BuildHostnameFile() error { + return err + } + container.HostnamePath = hostnamePath +- return ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644) ++ return os.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644) + } + + // NetworkMounts returns the list of network mounts. +@@ -407,7 +406,7 @@ func ignoreUnsupportedXAttrs() fs.CopyDirOpt { + // copyExistingContents copies from the source to the destination and + // ensures the ownership is appropriately set. + func copyExistingContents(source, destination string) error { +- dstList, err := ioutil.ReadDir(destination) ++ dstList, err := os.ReadDir(destination) + if err != nil { + return err + } +diff --git a/container/stream/streams.go b/container/stream/streams.go +index 585f9e8e3a..83e6ded611 100644 +--- a/container/stream/streams.go ++++ b/container/stream/streams.go +@@ -4,7 +4,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "strings" + "sync" + +@@ -87,7 +86,7 @@ func (c *Config) NewInputPipes() { + + // NewNopInputPipe creates a new input pipe that will silently drop all messages in the input. + func (c *Config) NewNopInputPipe() { +- c.stdinPipe = ioutils.NopWriteCloser(ioutil.Discard) ++ c.stdinPipe = ioutils.NopWriteCloser(io.Discard) + } + + // CloseStreams ensures that the configured streams are properly closed. +diff --git a/container/view_test.go b/container/view_test.go +index 4bd639bae9..290282c907 100644 +--- a/container/view_test.go ++++ b/container/view_test.go +@@ -1,7 +1,6 @@ + package container // import "github.com/docker/docker/container" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -17,7 +16,7 @@ var root string + + func TestMain(m *testing.M) { + var err error +- root, err = ioutil.TempDir("", "docker-container-test-") ++ root, err = os.MkdirTemp("", "docker-container-test-") + if err != nil { + panic(err) + } +diff --git a/daemon/checkpoint.go b/daemon/checkpoint.go +index 3ec581e5fc..5cbe8574ab 100644 +--- a/daemon/checkpoint.go ++++ b/daemon/checkpoint.go +@@ -3,7 +3,6 @@ package daemon // import "github.com/docker/docker/daemon" + import ( + "context" + "fmt" +- "io/ioutil" + "os" + "path/filepath" + +@@ -113,7 +112,7 @@ func (daemon *Daemon) CheckpointList(name string, config types.CheckpointListOpt + return nil, err + } + +- dirs, err := ioutil.ReadDir(checkpointDir) ++ dirs, err := os.ReadDir(checkpointDir) + if err != nil { + return nil, err + } +diff --git a/daemon/cluster/controllers/plugin/controller.go b/daemon/cluster/controllers/plugin/controller.go +index bad3d7243e..7d4b64a65d 100644 +--- a/daemon/cluster/controllers/plugin/controller.go ++++ b/daemon/cluster/controllers/plugin/controller.go +@@ -3,7 +3,6 @@ package plugin // import "github.com/docker/docker/daemon/cluster/controllers/pl + import ( + "context" + "io" +- "io/ioutil" + "net/http" + + "github.com/docker/distribution/reference" +@@ -118,10 +117,10 @@ func (p *Controller) Prepare(ctx context.Context) (err error) { + } + } + p.pluginID = pl.GetID() +- return p.backend.Upgrade(ctx, remote, p.spec.Name, nil, &authConfig, privs, ioutil.Discard) ++ return p.backend.Upgrade(ctx, remote, p.spec.Name, nil, &authConfig, privs, io.Discard) + } + +- if err := p.backend.Pull(ctx, remote, p.spec.Name, nil, &authConfig, privs, ioutil.Discard, plugin.WithSwarmService(p.serviceID), plugin.WithEnv(p.spec.Env)); err != nil { ++ if err := p.backend.Pull(ctx, remote, p.spec.Name, nil, &authConfig, privs, io.Discard, plugin.WithSwarmService(p.serviceID), plugin.WithEnv(p.spec.Env)); err != nil { + return err + } + pl, err = p.backend.Get(p.spec.Name) +diff --git a/daemon/cluster/controllers/plugin/controller_test.go b/daemon/cluster/controllers/plugin/controller_test.go +index 0611d59d9c..acba3ece8b 100644 +--- a/daemon/cluster/controllers/plugin/controller_test.go ++++ b/daemon/cluster/controllers/plugin/controller_test.go +@@ -4,7 +4,6 @@ import ( + "context" + "errors" + "io" +- "io/ioutil" + "net/http" + "strings" + "testing" +@@ -321,7 +320,7 @@ func TestRemove(t *testing.T) { + + func newTestController(b Backend, disabled bool) *Controller { + return &Controller{ +- logger: &logrus.Entry{Logger: &logrus.Logger{Out: ioutil.Discard}}, ++ logger: &logrus.Entry{Logger: &logrus.Logger{Out: io.Discard}}, + backend: b, + spec: runtime.PluginSpec{ + Name: pluginTestName, +diff --git a/daemon/cluster/executor/container/validate_test.go b/daemon/cluster/executor/container/validate_test.go +index 5e4694ff1b..a7fa270998 100644 +--- a/daemon/cluster/executor/container/validate_test.go ++++ b/daemon/cluster/executor/container/validate_test.go +@@ -1,7 +1,6 @@ + package container // import "github.com/docker/docker/daemon/cluster/executor/container" + + import ( +- "io/ioutil" + "os" + "strings" + "testing" +@@ -50,7 +49,7 @@ func TestControllerValidateMountBind(t *testing.T) { + } + + // with proper source +- tmpdir, err := ioutil.TempDir("", "TestControllerValidateMountBind") ++ tmpdir, err := os.MkdirTemp("", "TestControllerValidateMountBind") + if err != nil { + t.Fatalf("failed to create temp dir: %v", err) + } +@@ -86,7 +85,7 @@ func TestControllerValidateMountVolume(t *testing.T) { + } + + func TestControllerValidateMountTarget(t *testing.T) { +- tmpdir, err := ioutil.TempDir("", "TestControllerValidateMountTarget") ++ tmpdir, err := os.MkdirTemp("", "TestControllerValidateMountTarget") + if err != nil { + t.Fatalf("failed to create temp dir: %v", err) + } +diff --git a/daemon/cluster/utils.go b/daemon/cluster/utils.go +index d55e0012b7..e1493de413 100644 +--- a/daemon/cluster/utils.go ++++ b/daemon/cluster/utils.go +@@ -2,7 +2,6 @@ package cluster // import "github.com/docker/docker/daemon/cluster" + + import ( + "encoding/json" +- "io/ioutil" + "os" + "path/filepath" + +@@ -10,7 +9,7 @@ import ( + ) + + func loadPersistentState(root string) (*nodeStartConfig, error) { +- dt, err := ioutil.ReadFile(filepath.Join(root, stateFile)) ++ dt, err := os.ReadFile(filepath.Join(root, stateFile)) + if err != nil { + return nil, err + } +@@ -40,7 +39,7 @@ func clearPersistentState(root string) error { + // todo: backup this data instead of removing? + // rather than delete the entire swarm directory, delete the contents in order to preserve the inode + // (for example, allowing it to be bind-mounted) +- files, err := ioutil.ReadDir(root) ++ files, err := os.ReadDir(root) + if err != nil { + return err + } +diff --git a/daemon/config/config.go b/daemon/config/config.go +index 4990727597..69971d370b 100644 +--- a/daemon/config/config.go ++++ b/daemon/config/config.go +@@ -5,7 +5,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net" + "os" + "reflect" +@@ -388,7 +387,7 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *pflag.FlagSet, config + // It compares that configuration with the one provided by the flags, + // and returns an error if there are conflicts. + func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Config, error) { +- b, err := ioutil.ReadFile(configFile) ++ b, err := os.ReadFile(configFile) + if err != nil { + return nil, err + } +diff --git a/daemon/config/config_test.go b/daemon/config/config_test.go +index 0af8883ff3..3929b8a2e5 100644 +--- a/daemon/config/config_test.go ++++ b/daemon/config/config_test.go +@@ -1,7 +1,6 @@ + package config // import "github.com/docker/docker/daemon/config" + + import ( +- "io/ioutil" + "os" + "strings" + "testing" +@@ -24,7 +23,7 @@ func TestDaemonConfigurationNotFound(t *testing.T) { + } + + func TestDaemonBrokenConfiguration(t *testing.T) { +- f, err := ioutil.TempFile("", "docker-config-") ++ f, err := os.CreateTemp("", "docker-config-") + if err != nil { + t.Fatal(err) + } +@@ -77,7 +76,7 @@ func TestFindConfigurationConflictsWithNamedOptions(t *testing.T) { + } + + func TestDaemonConfigurationMergeConflicts(t *testing.T) { +- f, err := ioutil.TempFile("", "docker-config-") ++ f, err := os.CreateTemp("", "docker-config-") + if err != nil { + t.Fatal(err) + } +@@ -100,7 +99,7 @@ func TestDaemonConfigurationMergeConflicts(t *testing.T) { + } + + func TestDaemonConfigurationMergeConcurrent(t *testing.T) { +- f, err := ioutil.TempFile("", "docker-config-") ++ f, err := os.CreateTemp("", "docker-config-") + if err != nil { + t.Fatal(err) + } +@@ -116,7 +115,7 @@ func TestDaemonConfigurationMergeConcurrent(t *testing.T) { + } + + func TestDaemonConfigurationMergeConcurrentError(t *testing.T) { +- f, err := ioutil.TempFile("", "docker-config-") ++ f, err := os.CreateTemp("", "docker-config-") + if err != nil { + t.Fatal(err) + } +@@ -132,7 +131,7 @@ func TestDaemonConfigurationMergeConcurrentError(t *testing.T) { + } + + func TestDaemonConfigurationMergeConflictsWithInnerStructs(t *testing.T) { +- f, err := ioutil.TempFile("", "docker-config-") ++ f, err := os.CreateTemp("", "docker-config-") + if err != nil { + t.Fatal(err) + } +@@ -539,7 +538,7 @@ func TestReloadDefaultConfigNotExist(t *testing.T) { + // TestReloadBadDefaultConfig tests that when `--config-file` is not set + // and the default configuration file exists and is bad return an error + func TestReloadBadDefaultConfig(t *testing.T) { +- f, err := ioutil.TempFile("", "docker-config-") ++ f, err := os.CreateTemp("", "docker-config-") + if err != nil { + t.Fatal(err) + } +diff --git a/daemon/config/config_windows_test.go b/daemon/config/config_windows_test.go +index 6a4a8cb4fc..f4d507f0db 100644 +--- a/daemon/config/config_windows_test.go ++++ b/daemon/config/config_windows_test.go +@@ -4,7 +4,7 @@ + package config // import "github.com/docker/docker/daemon/config" + + import ( +- "io/ioutil" ++ "os" + "testing" + + "github.com/docker/docker/opts" +@@ -14,7 +14,7 @@ import ( + ) + + func TestDaemonConfigurationMerge(t *testing.T) { +- f, err := ioutil.TempFile("", "docker-config-") ++ f, err := os.CreateTemp("", "docker-config-") + if err != nil { + t.Fatal(err) + } +diff --git a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go +index 75b4b09b8d..beb1db8957 100644 +--- a/daemon/container_operations_unix.go ++++ b/daemon/container_operations_unix.go +@@ -5,7 +5,6 @@ package daemon // import "github.com/docker/docker/daemon" + + import ( + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "strconv" +@@ -206,7 +205,7 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) { + if err != nil { + return errors.Wrap(err, "unable to get secret from secret store") + } +- if err := ioutil.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil { ++ if err := os.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil { + return errors.Wrap(err, "error injecting secret") + } + +@@ -257,7 +256,7 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) { + if err != nil { + return errors.Wrap(err, "unable to get config from config store") + } +- if err := ioutil.WriteFile(fPath, config.Spec.Data, configRef.File.Mode); err != nil { ++ if err := os.WriteFile(fPath, config.Spec.Data, configRef.File.Mode); err != nil { + return errors.Wrap(err, "error injecting config") + } + +diff --git a/daemon/container_operations_windows.go b/daemon/container_operations_windows.go +index cc56bf4c79..af4ea785ef 100644 +--- a/daemon/container_operations_windows.go ++++ b/daemon/container_operations_windows.go +@@ -2,7 +2,6 @@ package daemon // import "github.com/docker/docker/daemon" + + import ( + "fmt" +- "io/ioutil" + "os" + + "github.com/docker/docker/container" +@@ -66,7 +65,7 @@ func (daemon *Daemon) setupConfigDir(c *container.Container) (setupErr error) { + if err != nil { + return errors.Wrap(err, "unable to get config from config store") + } +- if err := ioutil.WriteFile(fPath, config.Spec.Data, configRef.File.Mode); err != nil { ++ if err := os.WriteFile(fPath, config.Spec.Data, configRef.File.Mode); err != nil { + return errors.Wrap(err, "error injecting config") + } + } +@@ -137,7 +136,7 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) { + if err != nil { + return errors.Wrap(err, "unable to get secret from secret store") + } +- if err := ioutil.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil { ++ if err := os.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil { + return errors.Wrap(err, "error injecting secret") + } + } +diff --git a/daemon/daemon.go b/daemon/daemon.go +index f15a4b0384..2b5de96dba 100644 +--- a/daemon/daemon.go ++++ b/daemon/daemon.go +@@ -8,7 +8,6 @@ package daemon // import "github.com/docker/docker/daemon" + import ( + "context" + "fmt" +- "io/ioutil" + "net" + "net/url" + "os" +@@ -197,7 +196,7 @@ func (daemon *Daemon) RegistryHosts() docker.RegistryHosts { + } + + certsDir := registry.CertsDir() +- if fis, err := ioutil.ReadDir(certsDir); err == nil { ++ if fis, err := os.ReadDir(certsDir); err == nil { + for _, fi := range fis { + if _, ok := m[fi.Name()]; !ok { + m[fi.Name()] = bkconfig.RegistryConfig{ +@@ -216,7 +215,7 @@ func (daemon *Daemon) restore() error { + + logrus.Info("Loading containers: start.") + +- dir, err := ioutil.ReadDir(daemon.repository) ++ dir, err := os.ReadDir(daemon.repository) + if err != nil { + return err + } +diff --git a/daemon/daemon_linux_test.go b/daemon/daemon_linux_test.go +index 78b41e6f0b..a1e53600c0 100644 +--- a/daemon/daemon_linux_test.go ++++ b/daemon/daemon_linux_test.go +@@ -4,7 +4,6 @@ + package daemon // import "github.com/docker/docker/daemon" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "strings" +@@ -186,7 +185,7 @@ func TestRootMountCleanup(t *testing.T) { + + t.Parallel() + +- testRoot, err := ioutil.TempDir("", t.Name()) ++ testRoot, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(testRoot) + cfg := &config.Config{} +@@ -258,7 +257,7 @@ func TestRootMountCleanup(t *testing.T) { + err = mount.MakeShared(testRoot) + assert.NilError(t, err) + defer mount.MakePrivate(testRoot) +- err = ioutil.WriteFile(unmountFile, nil, 0644) ++ err = os.WriteFile(unmountFile, nil, 0644) + assert.NilError(t, err) + + err = setupDaemonRootPropagation(cfg) +diff --git a/daemon/daemon_test.go b/daemon/daemon_test.go +index c29b2705ba..41a6f076d8 100644 +--- a/daemon/daemon_test.go ++++ b/daemon/daemon_test.go +@@ -1,7 +1,6 @@ + package daemon // import "github.com/docker/docker/daemon" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -147,7 +146,7 @@ func TestContainerInitDNS(t *testing.T) { + t.Skip("root required") // for chown + } + +- tmp, err := ioutil.TempDir("", "docker-container-test-") ++ tmp, err := os.MkdirTemp("", "docker-container-test-") + if err != nil { + t.Fatal(err) + } +@@ -181,7 +180,7 @@ func TestContainerInitDNS(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- if err = ioutil.WriteFile(configPath, []byte(config), 0644); err != nil { ++ if err = os.WriteFile(configPath, []byte(config), 0644); err != nil { + t.Fatal(err) + } + +@@ -194,7 +193,7 @@ func TestContainerInitDNS(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- if err = ioutil.WriteFile(hostConfigPath, []byte(hostConfig), 0644); err != nil { ++ if err = os.WriteFile(hostConfigPath, []byte(hostConfig), 0644); err != nil { + t.Fatal(err) + } + +diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go +index af6904dd28..2ec54d7bbc 100644 +--- a/daemon/daemon_unix.go ++++ b/daemon/daemon_unix.go +@@ -7,7 +7,6 @@ import ( + "bufio" + "context" + "fmt" +- "io/ioutil" + "net" + "os" + "path/filepath" +@@ -787,7 +786,7 @@ func checkSystem() error { + // configureMaxThreads sets the Go runtime max threads threshold + // which is 90% of the kernel setting from /proc/sys/kernel/threads-max + func configureMaxThreads(config *config.Config) error { +- mt, err := ioutil.ReadFile("/proc/sys/kernel/threads-max") ++ mt, err := os.ReadFile("/proc/sys/kernel/threads-max") + if err != nil { + return err + } +@@ -1293,7 +1292,7 @@ func setupDaemonRootPropagation(cfg *config.Config) error { + return errors.Wrap(err, "error creating dir to store mount cleanup file") + } + +- if err := ioutil.WriteFile(cleanupFile, nil, 0600); err != nil { ++ if err := os.WriteFile(cleanupFile, nil, 0600); err != nil { + return errors.Wrap(err, "error writing file to signal mount cleanup on shutdown") + } + return nil +@@ -1696,13 +1695,13 @@ func maybeCreateCPURealTimeFile(configValue int64, file string, path string) err + if configValue == 0 { + return nil + } +- return ioutil.WriteFile(filepath.Join(path, file), []byte(strconv.FormatInt(configValue, 10)), 0700) ++ return os.WriteFile(filepath.Join(path, file), []byte(strconv.FormatInt(configValue, 10)), 0700) + } + + func (daemon *Daemon) setupSeccompProfile() error { + if daemon.configStore.SeccompProfile != "" { + daemon.seccompProfilePath = daemon.configStore.SeccompProfile +- b, err := ioutil.ReadFile(daemon.configStore.SeccompProfile) ++ b, err := os.ReadFile(daemon.configStore.SeccompProfile) + if err != nil { + return fmt.Errorf("opening seccomp profile (%s) failed: %v", daemon.configStore.SeccompProfile, err) + } +diff --git a/daemon/daemon_unix_test.go b/daemon/daemon_unix_test.go +index cdad58596e..65244ad576 100644 +--- a/daemon/daemon_unix_test.go ++++ b/daemon/daemon_unix_test.go +@@ -5,7 +5,6 @@ package daemon // import "github.com/docker/docker/daemon" + + import ( + "errors" +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -60,7 +59,7 @@ func TestAdjustSharedNamespaceContainerName(t *testing.T) { + + // Unix test as uses settings which are not available on Windows + func TestAdjustCPUShares(t *testing.T) { +- tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-") ++ tmp, err := os.MkdirTemp("", "docker-daemon-unix-test-") + if err != nil { + t.Fatal(err) + } +@@ -100,7 +99,7 @@ func TestAdjustCPUShares(t *testing.T) { + + // Unix test as uses settings which are not available on Windows + func TestAdjustCPUSharesNoAdjustment(t *testing.T) { +- tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-") ++ tmp, err := os.MkdirTemp("", "docker-daemon-unix-test-") + if err != nil { + t.Fatal(err) + } +@@ -397,7 +396,7 @@ func deviceTypeMock(t *testing.T, testAndCheck func(string)) { + + t.Parallel() + +- tempDir, err := ioutil.TempDir("", "tempDevDir"+t.Name()) ++ tempDir, err := os.MkdirTemp("", "tempDevDir"+t.Name()) + assert.NilError(t, err, "create temp file") + tempFile := filepath.Join(tempDir, "dev") + +diff --git a/daemon/delete_test.go b/daemon/delete_test.go +index 6c10987a3c..c95309e012 100644 +--- a/daemon/delete_test.go ++++ b/daemon/delete_test.go +@@ -2,7 +2,6 @@ package daemon // import "github.com/docker/docker/daemon" + + import ( + "fmt" +- "io/ioutil" + "os" + "testing" + +@@ -14,7 +13,7 @@ import ( + ) + + func newDaemonWithTmpRoot(t *testing.T) (*Daemon, func()) { +- tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-") ++ tmp, err := os.MkdirTemp("", "docker-daemon-unix-test-") + assert.NilError(t, err) + d := &Daemon{ + repository: tmp, +diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go +index 779e3c4dd8..4450a2e093 100644 +--- a/daemon/graphdriver/aufs/aufs.go ++++ b/daemon/graphdriver/aufs/aufs.go +@@ -28,7 +28,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "os" + "os/exec" + "path" +@@ -154,7 +153,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap + + for _, path := range []string{"mnt", "diff"} { + p := filepath.Join(root, path) +- entries, err := ioutil.ReadDir(p) ++ entries, err := os.ReadDir(p) + if err != nil { + logger.WithError(err).WithField("dir", p).Error("error reading dir entries") + continue +@@ -553,7 +552,7 @@ func (a *Driver) mounted(mountpoint string) (bool, error) { + // Cleanup aufs and unmount all mountpoints + func (a *Driver) Cleanup() error { + dir := a.mntPath() +- files, err := ioutil.ReadDir(dir) ++ files, err := os.ReadDir(dir) + if err != nil { + return errors.Wrap(err, "aufs readdir error") + } +@@ -636,14 +635,14 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro + // version of aufs. + func useDirperm() bool { + enableDirpermLock.Do(func() { +- base, err := ioutil.TempDir("", "docker-aufs-base") ++ base, err := os.MkdirTemp("", "docker-aufs-base") + if err != nil { + logger.Errorf("error checking dirperm1: %v", err) + return + } + defer os.RemoveAll(base) + +- union, err := ioutil.TempDir("", "docker-aufs-union") ++ union, err := os.MkdirTemp("", "docker-aufs-union") + if err != nil { + logger.Errorf("error checking dirperm1: %v", err) + return +diff --git a/daemon/graphdriver/aufs/aufs_test.go b/daemon/graphdriver/aufs/aufs_test.go +index b79225f20d..4c902f7848 100644 +--- a/daemon/graphdriver/aufs/aufs_test.go ++++ b/daemon/graphdriver/aufs/aufs_test.go +@@ -7,7 +7,6 @@ import ( + "crypto/sha256" + "encoding/hex" + "fmt" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -691,7 +690,7 @@ func testMountMoreThan42Layers(t *testing.T, mountPath string) { + // Perform the actual mount for the top most image + point, err := driverGet(d, last, "") + assert.NilError(t, err) +- files, err := ioutil.ReadDir(point) ++ files, err := os.ReadDir(point) + assert.NilError(t, err) + assert.Check(t, is.Len(files, expected)) + } +diff --git a/daemon/graphdriver/aufs/dirs.go b/daemon/graphdriver/aufs/dirs.go +index 161ca92714..006c556c07 100644 +--- a/daemon/graphdriver/aufs/dirs.go ++++ b/daemon/graphdriver/aufs/dirs.go +@@ -5,14 +5,13 @@ package aufs // import "github.com/docker/docker/daemon/graphdriver/aufs" + + import ( + "bufio" +- "io/ioutil" + "os" + "path" + ) + + // Return all the directories + func loadIds(root string) ([]string, error) { +- dirs, err := ioutil.ReadDir(root) ++ dirs, err := os.ReadDir(root) + if err != nil { + return nil, err + } +diff --git a/daemon/graphdriver/btrfs/btrfs.go b/daemon/graphdriver/btrfs/btrfs.go +index 88b05f98ec..8ce08b3e97 100644 +--- a/daemon/graphdriver/btrfs/btrfs.go ++++ b/daemon/graphdriver/btrfs/btrfs.go +@@ -20,7 +20,6 @@ import "C" + + import ( + "fmt" +- "io/ioutil" + "math" + "os" + "path" +@@ -577,7 +576,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { + if err := idtools.MkdirAllAndChown(quotas, 0700, idtools.CurrentIdentity()); err != nil { + return err + } +- if err := ioutil.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(driver.options.size)), 0644); err != nil { ++ if err := os.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(driver.options.size)), 0644); err != nil { + return err + } + } +@@ -678,7 +677,7 @@ func (d *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) { + return nil, fmt.Errorf("%s: not a directory", dir) + } + +- if quota, err := ioutil.ReadFile(d.quotasDirID(id)); err == nil { ++ if quota, err := os.ReadFile(d.quotasDirID(id)); err == nil { + if size, err := strconv.ParseUint(string(quota), 10, 64); err == nil && size >= d.options.minSpace { + if err := d.subvolEnableQuota(); err != nil { + return nil, err +diff --git a/daemon/graphdriver/copy/copy_test.go b/daemon/graphdriver/copy/copy_test.go +index aa1e957592..57ca3e5483 100644 +--- a/daemon/graphdriver/copy/copy_test.go ++++ b/daemon/graphdriver/copy/copy_test.go +@@ -5,7 +5,6 @@ package copy // import "github.com/docker/docker/daemon/graphdriver/copy" + + import ( + "fmt" +- "io/ioutil" + "math/rand" + "os" + "path/filepath" +@@ -32,11 +31,11 @@ func TestCopyWithoutRange(t *testing.T) { + } + + func TestCopyDir(t *testing.T) { +- srcDir, err := ioutil.TempDir("", "srcDir") ++ srcDir, err := os.MkdirTemp("", "srcDir") + assert.NilError(t, err) + populateSrcDir(t, srcDir, 3) + +- dstDir, err := ioutil.TempDir("", "testdst") ++ dstDir, err := os.MkdirTemp("", "testdst") + assert.NilError(t, err) + defer os.RemoveAll(dstDir) + +@@ -102,13 +101,13 @@ func populateSrcDir(t *testing.T, srcDir string, remainingDepth int) { + for i := 0; i < 10; i++ { + fileName := filepath.Join(srcDir, fmt.Sprintf("srcfile-%d", i)) + // Owner read bit set +- assert.NilError(t, ioutil.WriteFile(fileName, []byte{}, randomMode(0400))) ++ assert.NilError(t, os.WriteFile(fileName, []byte{}, randomMode(0400))) + assert.NilError(t, system.Chtimes(fileName, aTime, mTime)) + } + } + + func doCopyTest(t *testing.T, copyWithFileRange, copyWithFileClone *bool) { +- dir, err := ioutil.TempDir("", "docker-copy-check") ++ dir, err := os.MkdirTemp("", "docker-copy-check") + assert.NilError(t, err) + defer os.RemoveAll(dir) + srcFilename := filepath.Join(dir, "srcFilename") +@@ -118,12 +117,12 @@ func doCopyTest(t *testing.T, copyWithFileRange, copyWithFileClone *bool) { + buf := make([]byte, 1024) + _, err = r.Read(buf) + assert.NilError(t, err) +- assert.NilError(t, ioutil.WriteFile(srcFilename, buf, 0777)) ++ assert.NilError(t, os.WriteFile(srcFilename, buf, 0777)) + fileinfo, err := os.Stat(srcFilename) + assert.NilError(t, err) + + assert.NilError(t, copyRegular(srcFilename, dstFilename, fileinfo, copyWithFileRange, copyWithFileClone)) +- readBuf, err := ioutil.ReadFile(dstFilename) ++ readBuf, err := os.ReadFile(dstFilename) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(buf, readBuf)) + } +@@ -131,11 +130,11 @@ func doCopyTest(t *testing.T, copyWithFileRange, copyWithFileClone *bool) { + func TestCopyHardlink(t *testing.T) { + var srcFile1FileInfo, srcFile2FileInfo, dstFile1FileInfo, dstFile2FileInfo unix.Stat_t + +- srcDir, err := ioutil.TempDir("", "srcDir") ++ srcDir, err := os.MkdirTemp("", "srcDir") + assert.NilError(t, err) + defer os.RemoveAll(srcDir) + +- dstDir, err := ioutil.TempDir("", "dstDir") ++ dstDir, err := os.MkdirTemp("", "dstDir") + assert.NilError(t, err) + defer os.RemoveAll(dstDir) + +@@ -143,7 +142,7 @@ func TestCopyHardlink(t *testing.T) { + srcFile2 := filepath.Join(srcDir, "file2") + dstFile1 := filepath.Join(dstDir, "file1") + dstFile2 := filepath.Join(dstDir, "file2") +- assert.NilError(t, ioutil.WriteFile(srcFile1, []byte{}, 0777)) ++ assert.NilError(t, os.WriteFile(srcFile1, []byte{}, 0777)) + assert.NilError(t, os.Link(srcFile1, srcFile2)) + + assert.Check(t, DirCopy(srcDir, dstDir, Content, false)) +diff --git a/daemon/graphdriver/devmapper/device_setup.go b/daemon/graphdriver/devmapper/device_setup.go +index e03e23c92f..ec3d3aa93c 100644 +--- a/daemon/graphdriver/devmapper/device_setup.go ++++ b/daemon/graphdriver/devmapper/device_setup.go +@@ -5,7 +5,6 @@ import ( + "bytes" + "encoding/json" + "fmt" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -139,7 +138,7 @@ func readLVMConfig(root string) (directLVMConfig, error) { + var cfg directLVMConfig + + p := filepath.Join(root, "setup-config.json") +- b, err := ioutil.ReadFile(p) ++ b, err := os.ReadFile(p) + if err != nil { + if os.IsNotExist(err) { + return cfg, nil +@@ -162,7 +161,7 @@ func writeLVMConfig(root string, cfg directLVMConfig) error { + if err != nil { + return errors.Wrap(err, "error marshalling direct lvm config") + } +- err = ioutil.WriteFile(p, b, 0600) ++ err = os.WriteFile(p, b, 0600) + return errors.Wrap(err, "error writing direct lvm config to file") + } + +@@ -221,7 +220,7 @@ func setupDirectLVM(cfg directLVMConfig) error { + } + + profile := fmt.Sprintf("activation{\nthin_pool_autoextend_threshold=%d\nthin_pool_autoextend_percent=%d\n}", cfg.AutoExtendThreshold, cfg.AutoExtendPercent) +- err = ioutil.WriteFile(lvmProfileDir+"/docker-thinpool.profile", []byte(profile), 0600) ++ err = os.WriteFile(lvmProfileDir+"/docker-thinpool.profile", []byte(profile), 0600) + if err != nil { + return errors.Wrap(err, "error writing docker thinp autoextend profile") + } +diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go +index 9bcef1225d..e9c4634b67 100644 +--- a/daemon/graphdriver/devmapper/deviceset.go ++++ b/daemon/graphdriver/devmapper/deviceset.go +@@ -8,7 +8,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "os" + "os/exec" + "path" +@@ -326,7 +325,7 @@ func (devices *DeviceSet) removeMetadata(info *devInfo) error { + + // Given json data and file path, write it to disk + func (devices *DeviceSet) writeMetaFile(jsonData []byte, filePath string) error { +- tmpFile, err := ioutil.TempFile(devices.metadataDir(), ".tmp") ++ tmpFile, err := os.CreateTemp(devices.metadataDir(), ".tmp") + if err != nil { + return fmt.Errorf("devmapper: Error creating metadata file: %s", err) + } +@@ -541,7 +540,7 @@ func xfsSupported() error { + return err // error text is descriptive enough + } + +- mountTarget, err := ioutil.TempDir("", "supportsXFS") ++ mountTarget, err := os.MkdirTemp("", "supportsXFS") + if err != nil { + return errors.Wrapf(err, "error checking for xfs support") + } +@@ -634,7 +633,7 @@ func (devices *DeviceSet) createFilesystem(info *devInfo) (err error) { + + func (devices *DeviceSet) migrateOldMetaData() error { + // Migrate old metadata file +- jsonData, err := ioutil.ReadFile(devices.oldMetadataFile()) ++ jsonData, err := os.ReadFile(devices.oldMetadataFile()) + if err != nil && !os.IsNotExist(err) { + return err + } +@@ -956,7 +955,7 @@ func (devices *DeviceSet) loadMetadata(hash string) *devInfo { + info := &devInfo{Hash: hash, devices: devices} + logger := logrus.WithField("storage-driver", "devicemapper") + +- jsonData, err := ioutil.ReadFile(devices.metadataFile(info)) ++ jsonData, err := os.ReadFile(devices.metadataFile(info)) + if err != nil { + logger.Debugf("Failed to read %s with err: %v", devices.metadataFile(info), err) + return nil +@@ -1264,7 +1263,7 @@ func (devices *DeviceSet) setupBaseImage() error { + } + + func setCloseOnExec(name string) { +- fileInfos, _ := ioutil.ReadDir("/proc/self/fd") ++ fileInfos, _ := os.ReadDir("/proc/self/fd") + for _, i := range fileInfos { + link, _ := os.Readlink(filepath.Join("/proc/self/fd", i.Name())) + if link == name { +@@ -1358,7 +1357,7 @@ func (devices *DeviceSet) ResizePool(size int64) error { + } + + func (devices *DeviceSet) loadTransactionMetaData() error { +- jsonData, err := ioutil.ReadFile(devices.transactionMetaFile()) ++ jsonData, err := os.ReadFile(devices.transactionMetaFile()) + if err != nil { + // There is no active transaction. This will be the case + // during upgrade. +@@ -1441,7 +1440,7 @@ func (devices *DeviceSet) processPendingTransaction() error { + } + + func (devices *DeviceSet) loadDeviceSetMetaData() error { +- jsonData, err := ioutil.ReadFile(devices.deviceSetMetaFile()) ++ jsonData, err := os.ReadFile(devices.deviceSetMetaFile()) + if err != nil { + // For backward compatibility return success if file does + // not exist. +@@ -2246,7 +2245,7 @@ func (devices *DeviceSet) cancelDeferredRemoval(info *devInfo) error { + func (devices *DeviceSet) unmountAndDeactivateAll(dir string) { + logger := logrus.WithField("storage-driver", "devicemapper") + +- files, err := ioutil.ReadDir(dir) ++ files, err := os.ReadDir(dir) + if err != nil { + logger.Warnf("unmountAndDeactivate: %s", err) + return +diff --git a/daemon/graphdriver/devmapper/driver.go b/daemon/graphdriver/devmapper/driver.go +index d6e172cf6e..7abdbe6163 100644 +--- a/daemon/graphdriver/devmapper/driver.go ++++ b/daemon/graphdriver/devmapper/driver.go +@@ -5,7 +5,6 @@ package devmapper // import "github.com/docker/docker/daemon/graphdriver/devmapp + + import ( + "fmt" +- "io/ioutil" + "os" + "path" + "strconv" +@@ -221,7 +220,7 @@ func (d *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) { + if _, err := os.Stat(idFile); err != nil && os.IsNotExist(err) { + // Create an "id" file with the container/image id in it to help reconstruct this in case + // of later problems +- if err := ioutil.WriteFile(idFile, []byte(id), 0600); err != nil { ++ if err := os.WriteFile(idFile, []byte(id), 0600); err != nil { + d.ctr.Decrement(mp) + d.DeviceSet.UnmountDevice(id, mp) + return nil, err +diff --git a/daemon/graphdriver/driver_test.go b/daemon/graphdriver/driver_test.go +index e89165f540..474370203f 100644 +--- a/daemon/graphdriver/driver_test.go ++++ b/daemon/graphdriver/driver_test.go +@@ -1,7 +1,6 @@ + package graphdriver // import "github.com/docker/docker/daemon/graphdriver" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -10,7 +9,7 @@ import ( + ) + + func TestIsEmptyDir(t *testing.T) { +- tmp, err := ioutil.TempDir("", "test-is-empty-dir") ++ tmp, err := os.MkdirTemp("", "test-is-empty-dir") + assert.NilError(t, err) + defer os.RemoveAll(tmp) + +@@ -29,7 +28,7 @@ func TestIsEmptyDir(t *testing.T) { + d = filepath.Join(tmp, "dir-with-empty-file") + err = os.Mkdir(d, 0755) + assert.NilError(t, err) +- _, err = ioutil.TempFile(d, "file") ++ _, err = os.CreateTemp(d, "file") + assert.NilError(t, err) + empty = isEmptyDir(d) + assert.Check(t, !empty) +diff --git a/daemon/graphdriver/fuse-overlayfs/fuseoverlayfs.go b/daemon/graphdriver/fuse-overlayfs/fuseoverlayfs.go +index 1c236f9213..fa1d63453b 100644 +--- a/daemon/graphdriver/fuse-overlayfs/fuseoverlayfs.go ++++ b/daemon/graphdriver/fuse-overlayfs/fuseoverlayfs.go +@@ -8,7 +8,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "os" + "os/exec" + "path" +@@ -217,7 +216,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + } + + // Write link id to link file +- if err := ioutil.WriteFile(path.Join(dir, "link"), []byte(lid), 0644); err != nil { ++ if err := os.WriteFile(path.Join(dir, "link"), []byte(lid), 0644); err != nil { + return err + } + +@@ -230,7 +229,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + return err + } + +- if err := ioutil.WriteFile(path.Join(d.dir(parent), "committed"), []byte{}, 0600); err != nil { ++ if err := os.WriteFile(path.Join(d.dir(parent), "committed"), []byte{}, 0600); err != nil { + return err + } + +@@ -239,7 +238,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + return err + } + if lower != "" { +- if err := ioutil.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err != nil { ++ if err := os.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err != nil { + return err + } + } +@@ -256,13 +255,13 @@ func (d *Driver) getLower(parent string) (string, error) { + } + + // Read Parent link fileA +- parentLink, err := ioutil.ReadFile(path.Join(parentDir, "link")) ++ parentLink, err := os.ReadFile(path.Join(parentDir, "link")) + if err != nil { + return "", err + } + lowers := []string{path.Join(linkDir, string(parentLink))} + +- parentLower, err := ioutil.ReadFile(path.Join(parentDir, lowerFile)) ++ parentLower, err := os.ReadFile(path.Join(parentDir, lowerFile)) + if err == nil { + parentLowers := strings.Split(string(parentLower), ":") + lowers = append(lowers, parentLowers...) +@@ -279,7 +278,7 @@ func (d *Driver) dir(id string) string { + + func (d *Driver) getLowerDirs(id string) ([]string, error) { + var lowersArray []string +- lowers, err := ioutil.ReadFile(path.Join(d.dir(id), lowerFile)) ++ lowers, err := os.ReadFile(path.Join(d.dir(id), lowerFile)) + if err == nil { + for _, s := range strings.Split(string(lowers), ":") { + lp, err := os.Readlink(path.Join(d.home, s)) +@@ -302,7 +301,7 @@ func (d *Driver) Remove(id string) error { + d.locker.Lock(id) + defer d.locker.Unlock(id) + dir := d.dir(id) +- lid, err := ioutil.ReadFile(path.Join(dir, "link")) ++ lid, err := os.ReadFile(path.Join(dir, "link")) + if err == nil { + if len(lid) == 0 { + logger.Errorf("refusing to remove empty link for layer %v", id) +@@ -327,7 +326,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e + } + + diffDir := path.Join(dir, diffDirName) +- lowers, err := ioutil.ReadFile(path.Join(dir, lowerFile)) ++ lowers, err := os.ReadFile(path.Join(dir, lowerFile)) + if err != nil { + // If no lower, just return diff directory + if os.IsNotExist(err) { +@@ -409,7 +408,7 @@ func (d *Driver) Put(id string) error { + d.locker.Lock(id) + defer d.locker.Unlock(id) + dir := d.dir(id) +- _, err := ioutil.ReadFile(path.Join(dir, lowerFile)) ++ _, err := os.ReadFile(path.Join(dir, lowerFile)) + if err != nil { + // If no lower, no mount happened and just return directly + if os.IsNotExist(err) { +diff --git a/daemon/graphdriver/graphtest/graphbench_unix.go b/daemon/graphdriver/graphtest/graphbench_unix.go +index bd677054bc..378794a531 100644 +--- a/daemon/graphdriver/graphtest/graphbench_unix.go ++++ b/daemon/graphdriver/graphtest/graphbench_unix.go +@@ -5,7 +5,6 @@ package graphtest // import "github.com/docker/docker/daemon/graphdriver/graphte + + import ( + "io" +- "io/ioutil" + "testing" + + contdriver "github.com/containerd/continuity/driver" +@@ -77,7 +76,7 @@ func DriverBenchDiffBase(b *testing.B, drivername string, driveroptions ...strin + if err != nil { + b.Fatal(err) + } +- _, err = io.Copy(ioutil.Discard, arch) ++ _, err = io.Copy(io.Discard, arch) + if err != nil { + b.Fatalf("Error copying archive: %s", err) + } +@@ -113,7 +112,7 @@ func DriverBenchDiffN(b *testing.B, bottom, top int, drivername string, driverop + if err != nil { + b.Fatal(err) + } +- _, err = io.Copy(ioutil.Discard, arch) ++ _, err = io.Copy(io.Discard, arch) + if err != nil { + b.Fatalf("Error copying archive: %s", err) + } +@@ -212,7 +211,7 @@ func DriverBenchDeepLayerDiff(b *testing.B, layerCount int, drivername string, d + if err != nil { + b.Fatal(err) + } +- _, err = io.Copy(ioutil.Discard, arch) ++ _, err = io.Copy(io.Discard, arch) + if err != nil { + b.Fatalf("Error copying archive: %s", err) + } +diff --git a/daemon/graphdriver/graphtest/graphtest_unix.go b/daemon/graphdriver/graphtest/graphtest_unix.go +index 464ab9bedf..1fc91ea012 100644 +--- a/daemon/graphdriver/graphtest/graphtest_unix.go ++++ b/daemon/graphdriver/graphtest/graphtest_unix.go +@@ -5,7 +5,6 @@ package graphtest // import "github.com/docker/docker/daemon/graphdriver/graphte + + import ( + "bytes" +- "io/ioutil" + "math/rand" + "os" + "path" +@@ -36,7 +35,7 @@ type Driver struct { + } + + func newDriver(t testing.TB, name string, options []string) *Driver { +- root, err := ioutil.TempDir("", "docker-graphtest-") ++ root, err := os.MkdirTemp("", "docker-graphtest-") + assert.NilError(t, err) + + assert.NilError(t, os.MkdirAll(root, 0755)) +@@ -308,7 +307,7 @@ func writeRandomFile(path string, size uint64) error { + header.Cap *= 8 + data := *(*[]byte)(unsafe.Pointer(&header)) //nolint:govet // FIXME: unsafeptr: possible misuse of reflect.SliceHeader (govet) see https://github.com/moby/moby/issues/42444 + +- return ioutil.WriteFile(path, data, 0700) ++ return os.WriteFile(path, data, 0700) + } + + // DriverTestSetQuota Create a driver and test setting quota. +diff --git a/daemon/graphdriver/lcow/lcow.go b/daemon/graphdriver/lcow/lcow.go +index 9e94bb228d..f154743f9c 100644 +--- a/daemon/graphdriver/lcow/lcow.go ++++ b/daemon/graphdriver/lcow/lcow.go +@@ -48,7 +48,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -743,7 +742,7 @@ func (d *Driver) Put(id string) error { + func (d *Driver) Cleanup() error { + title := "lcowdriver: cleanup" + +- items, err := ioutil.ReadDir(d.dataRoot) ++ items, err := os.ReadDir(d.dataRoot) + if err != nil { + if os.IsNotExist(err) { + return nil +@@ -972,7 +971,7 @@ func (d *Driver) dir(id string) string { + func (d *Driver) getLayerChain(id string) ([]string, error) { + jPath := filepath.Join(d.dir(id), "layerchain.json") + logrus.Debugf("lcowdriver: getlayerchain: id %s json %s", id, jPath) +- content, err := ioutil.ReadFile(jPath) ++ content, err := os.ReadFile(jPath) + if os.IsNotExist(err) { + return nil, nil + } else if err != nil { +@@ -996,7 +995,7 @@ func (d *Driver) setLayerChain(id string, chain []string) error { + + jPath := filepath.Join(d.dir(id), "layerchain.json") + logrus.Debugf("lcowdriver: setlayerchain: id %s json %s", id, jPath) +- err = ioutil.WriteFile(jPath, content, 0600) ++ err = os.WriteFile(jPath, content, 0600) + if err != nil { + return fmt.Errorf("lcowdriver: setlayerchain: %s failed to write layerchain file: %s", id, err) + } +diff --git a/daemon/graphdriver/overlay/overlay.go b/daemon/graphdriver/overlay/overlay.go +index 99ba139f62..6a51f59d55 100644 +--- a/daemon/graphdriver/overlay/overlay.go ++++ b/daemon/graphdriver/overlay/overlay.go +@@ -6,7 +6,6 @@ package overlay // import "github.com/docker/docker/daemon/graphdriver/overlay" + import ( + "fmt" + "io" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -229,7 +228,7 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) { + return metadata, nil + } + +- lowerID, err := ioutil.ReadFile(path.Join(dir, "lower-id")) ++ lowerID, err := os.ReadFile(path.Join(dir, "lower-id")) + if err != nil { + return nil, err + } +@@ -310,17 +309,17 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr + if err := idtools.MkdirAndChown(path.Join(dir, "work"), 0700, root); err != nil { + return err + } +- return ioutil.WriteFile(path.Join(dir, "lower-id"), []byte(parent), 0600) ++ return os.WriteFile(path.Join(dir, "lower-id"), []byte(parent), 0600) + } + + // Otherwise, copy the upper and the lower-id from the parent + +- lowerID, err := ioutil.ReadFile(path.Join(parentDir, "lower-id")) ++ lowerID, err := os.ReadFile(path.Join(parentDir, "lower-id")) + if err != nil { + return err + } + +- if err := ioutil.WriteFile(path.Join(dir, "lower-id"), lowerID, 0600); err != nil { ++ if err := os.WriteFile(path.Join(dir, "lower-id"), lowerID, 0600); err != nil { + return err + } + +@@ -386,7 +385,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, err erro + } + } + }() +- lowerID, err := ioutil.ReadFile(path.Join(dir, "lower-id")) ++ lowerID, err := os.ReadFile(path.Join(dir, "lower-id")) + if err != nil { + return nil, err + } +@@ -466,7 +465,7 @@ func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64 + // 2) ApplyDiff doesn't do any in-place writes to files (would break hardlinks) + // These are all currently true and are not expected to break + +- tmpRootDir, err := ioutil.TempDir(dir, "tmproot") ++ tmpRootDir, err := os.MkdirTemp(dir, "tmproot") + if err != nil { + return 0, err + } +diff --git a/daemon/graphdriver/overlay2/check.go b/daemon/graphdriver/overlay2/check.go +index 37db8b3ef3..feddf14dd1 100644 +--- a/daemon/graphdriver/overlay2/check.go ++++ b/daemon/graphdriver/overlay2/check.go +@@ -5,7 +5,6 @@ package overlay2 // import "github.com/docker/docker/daemon/graphdriver/overlay2 + + import ( + "fmt" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -29,7 +28,7 @@ func doesSupportNativeDiff(d string) error { + return errors.New("running in a user namespace") + } + +- td, err := ioutil.TempDir(d, "opaque-bug-check") ++ td, err := os.MkdirTemp(d, "opaque-bug-check") + if err != nil { + return err + } +@@ -75,7 +74,7 @@ func doesSupportNativeDiff(d string) error { + }() + + // Touch file in d to force copy up of opaque directory "d" from "l2" to "l3" +- if err := ioutil.WriteFile(filepath.Join(td, mergedDirName, "d", "f"), []byte{}, 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(td, mergedDirName, "d", "f"), []byte{}, 0644); err != nil { + return errors.Wrap(err, "failed to write to merged directory") + } + +diff --git a/daemon/graphdriver/overlay2/overlay.go b/daemon/graphdriver/overlay2/overlay.go +index 57b1bed888..444f600f55 100644 +--- a/daemon/graphdriver/overlay2/overlay.go ++++ b/daemon/graphdriver/overlay2/overlay.go +@@ -8,7 +8,6 @@ import ( + "errors" + "fmt" + "io" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -401,7 +400,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + } + + // Write link id to link file +- if err := ioutil.WriteFile(path.Join(dir, "link"), []byte(lid), 0644); err != nil { ++ if err := os.WriteFile(path.Join(dir, "link"), []byte(lid), 0644); err != nil { + return err + } + +@@ -414,7 +413,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + return err + } + +- if err := ioutil.WriteFile(path.Join(d.dir(parent), "committed"), []byte{}, 0600); err != nil { ++ if err := os.WriteFile(path.Join(d.dir(parent), "committed"), []byte{}, 0600); err != nil { + return err + } + +@@ -423,7 +422,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + return err + } + if lower != "" { +- if err := ioutil.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err != nil { ++ if err := os.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err != nil { + return err + } + } +@@ -460,13 +459,13 @@ func (d *Driver) getLower(parent string) (string, error) { + } + + // Read Parent link fileA +- parentLink, err := ioutil.ReadFile(path.Join(parentDir, "link")) ++ parentLink, err := os.ReadFile(path.Join(parentDir, "link")) + if err != nil { + return "", err + } + lowers := []string{path.Join(linkDir, string(parentLink))} + +- parentLower, err := ioutil.ReadFile(path.Join(parentDir, lowerFile)) ++ parentLower, err := os.ReadFile(path.Join(parentDir, lowerFile)) + if err == nil { + parentLowers := strings.Split(string(parentLower), ":") + lowers = append(lowers, parentLowers...) +@@ -483,7 +482,7 @@ func (d *Driver) dir(id string) string { + + func (d *Driver) getLowerDirs(id string) ([]string, error) { + var lowersArray []string +- lowers, err := ioutil.ReadFile(path.Join(d.dir(id), lowerFile)) ++ lowers, err := os.ReadFile(path.Join(d.dir(id), lowerFile)) + if err == nil { + for _, s := range strings.Split(string(lowers), ":") { + lp, err := os.Readlink(path.Join(d.home, s)) +@@ -506,7 +505,7 @@ func (d *Driver) Remove(id string) error { + d.locker.Lock(id) + defer d.locker.Unlock(id) + dir := d.dir(id) +- lid, err := ioutil.ReadFile(path.Join(dir, "link")) ++ lid, err := os.ReadFile(path.Join(dir, "link")) + if err == nil { + if len(lid) == 0 { + logger.Errorf("refusing to remove empty link for layer %v", id) +@@ -531,7 +530,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e + } + + diffDir := path.Join(dir, diffDirName) +- lowers, err := ioutil.ReadFile(path.Join(dir, lowerFile)) ++ lowers, err := os.ReadFile(path.Join(dir, lowerFile)) + if err != nil { + // If no lower, just return diff directory + if os.IsNotExist(err) { +@@ -635,7 +634,7 @@ func (d *Driver) Put(id string) error { + d.locker.Lock(id) + defer d.locker.Unlock(id) + dir := d.dir(id) +- _, err := ioutil.ReadFile(path.Join(dir, lowerFile)) ++ _, err := os.ReadFile(path.Join(dir, lowerFile)) + if err != nil { + // If no lower, no mount happened and just return directly + if os.IsNotExist(err) { +diff --git a/daemon/graphdriver/overlay2/overlay_test.go b/daemon/graphdriver/overlay2/overlay_test.go +index 261ee40005..47f3f11005 100644 +--- a/daemon/graphdriver/overlay2/overlay_test.go ++++ b/daemon/graphdriver/overlay2/overlay_test.go +@@ -4,7 +4,6 @@ + package overlay2 // import "github.com/docker/docker/daemon/graphdriver/overlay2" + + import ( +- "io/ioutil" + "os" + "testing" + +@@ -24,7 +23,7 @@ func init() { + } + + func skipIfNaive(t *testing.T) { +- td, err := ioutil.TempDir("", "naive-check-") ++ td, err := os.MkdirTemp("", "naive-check-") + if err != nil { + t.Fatalf("Failed to create temp dir: %v", err) + } +diff --git a/daemon/graphdriver/overlayutils/overlayutils.go b/daemon/graphdriver/overlayutils/overlayutils.go +index 26652d2fc2..5100c87bf9 100644 +--- a/daemon/graphdriver/overlayutils/overlayutils.go ++++ b/daemon/graphdriver/overlayutils/overlayutils.go +@@ -5,7 +5,6 @@ package overlayutils // import "github.com/docker/docker/daemon/graphdriver/over + + import ( + "fmt" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -48,7 +47,7 @@ func SupportsOverlay(d string, checkMultipleLowers bool) error { + return errors.New("overlay is not supported for Rootless with SELinux") + } + +- td, err := ioutil.TempDir(d, "check-overlayfs-support") ++ td, err := os.MkdirTemp(d, "check-overlayfs-support") + if err != nil { + return err + } +diff --git a/daemon/graphdriver/overlayutils/userxattr.go b/daemon/graphdriver/overlayutils/userxattr.go +index e516617b6b..254577d89c 100644 +--- a/daemon/graphdriver/overlayutils/userxattr.go ++++ b/daemon/graphdriver/overlayutils/userxattr.go +@@ -22,7 +22,6 @@ package overlayutils + + import ( + "fmt" +- "io/ioutil" + "os" + "path/filepath" + +@@ -81,7 +80,7 @@ func NeedsUserXAttr(d string) (bool, error) { + } + }() + +- td, err := ioutil.TempDir(tdRoot, "") ++ td, err := os.MkdirTemp(tdRoot, "") + if err != nil { + return false, err + } +diff --git a/daemon/graphdriver/windows/windows.go b/daemon/graphdriver/windows/windows.go +index f87c2703cb..e087c294be 100644 +--- a/daemon/graphdriver/windows/windows.go ++++ b/daemon/graphdriver/windows/windows.go +@@ -10,7 +10,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -451,7 +450,7 @@ func (d *Driver) Put(id string) error { + // We use this opportunity to cleanup any -removing folders which may be + // still left if the daemon was killed while it was removing a layer. + func (d *Driver) Cleanup() error { +- items, err := ioutil.ReadDir(d.info.HomeDir) ++ items, err := os.ReadDir(d.info.HomeDir) + if err != nil { + if os.IsNotExist(err) { + return nil +@@ -841,7 +840,7 @@ func writeLayer(layerData io.Reader, home string, id string, parentLayerPaths .. + + // resolveID computes the layerID information based on the given id. + func (d *Driver) resolveID(id string) (string, error) { +- content, err := ioutil.ReadFile(filepath.Join(d.dir(id), "layerID")) ++ content, err := os.ReadFile(filepath.Join(d.dir(id), "layerID")) + if os.IsNotExist(err) { + return id, nil + } else if err != nil { +@@ -852,13 +851,13 @@ func (d *Driver) resolveID(id string) (string, error) { + + // setID stores the layerId in disk. + func (d *Driver) setID(id, altID string) error { +- return ioutil.WriteFile(filepath.Join(d.dir(id), "layerId"), []byte(altID), 0600) ++ return os.WriteFile(filepath.Join(d.dir(id), "layerId"), []byte(altID), 0600) + } + + // getLayerChain returns the layer chain information. + func (d *Driver) getLayerChain(id string) ([]string, error) { + jPath := filepath.Join(d.dir(id), "layerchain.json") +- content, err := ioutil.ReadFile(jPath) ++ content, err := os.ReadFile(jPath) + if os.IsNotExist(err) { + return nil, nil + } else if err != nil { +@@ -882,7 +881,7 @@ func (d *Driver) setLayerChain(id string, chain []string) error { + } + + jPath := filepath.Join(d.dir(id), "layerchain.json") +- err = ioutil.WriteFile(jPath, content, 0600) ++ err = os.WriteFile(jPath, content, 0600) + if err != nil { + return fmt.Errorf("Unable to write layerchain file - %s", err) + } +diff --git a/daemon/images/image.go b/daemon/images/image.go +index cffa5414ae..8b96604781 100644 +--- a/daemon/images/image.go ++++ b/daemon/images/image.go +@@ -5,7 +5,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + + "github.com/containerd/containerd/content" + c8derrdefs "github.com/containerd/containerd/errdefs" +@@ -84,7 +83,7 @@ func (i *ImageService) manifestMatchesPlatform(img *image.Image, platform specs. + continue + } + +- data, err := ioutil.ReadAll(makeRdr(ra)) ++ data, err := io.ReadAll(makeRdr(ra)) + ra.Close() + + if err != nil { +@@ -124,7 +123,7 @@ func (i *ImageService) manifestMatchesPlatform(img *image.Image, platform specs. + continue + } + +- data, err := ioutil.ReadAll(makeRdr(ra)) ++ data, err := io.ReadAll(makeRdr(ra)) + ra.Close() + if err != nil { + logger.WithError(err).Error("Error reading manifest for image") +diff --git a/daemon/images/store_test.go b/daemon/images/store_test.go +index 212e362305..cbb723b4a2 100644 +--- a/daemon/images/store_test.go ++++ b/daemon/images/store_test.go +@@ -2,7 +2,6 @@ package images + + import ( + "context" +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -22,7 +21,7 @@ import ( + ) + + func setupTestStores(t *testing.T) (context.Context, content.Store, *imageStoreWithLease, func(t *testing.T)) { +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + + backend, err := image.NewFSStoreBackend(filepath.Join(dir, "images")) +diff --git a/daemon/keys.go b/daemon/keys.go +index 6cbc54ed7a..c386866f96 100644 +--- a/daemon/keys.go ++++ b/daemon/keys.go +@@ -5,7 +5,6 @@ package daemon // import "github.com/docker/docker/daemon" + + import ( + "fmt" +- "io/ioutil" + "os" + "strconv" + "strings" +@@ -52,7 +51,7 @@ func setRootKeyLimit(limit int) error { + } + + func readRootKeyLimit(path string) (int, error) { +- data, err := ioutil.ReadFile(path) ++ data, err := os.ReadFile(path) + if err != nil { + return -1, err + } +diff --git a/daemon/list_test.go b/daemon/list_test.go +index 504b240dfc..e6a7382bff 100644 +--- a/daemon/list_test.go ++++ b/daemon/list_test.go +@@ -1,7 +1,6 @@ + package daemon + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -21,7 +20,7 @@ var root string + + func TestMain(m *testing.M) { + var err error +- root, err = ioutil.TempDir("", "docker-container-test-") ++ root, err = os.MkdirTemp("", "docker-container-test-") + if err != nil { + panic(err) + } +diff --git a/daemon/logger/awslogs/cloudwatchlogs_test.go b/daemon/logger/awslogs/cloudwatchlogs_test.go +index 80a2da1395..688a3b5e2f 100644 +--- a/daemon/logger/awslogs/cloudwatchlogs_test.go ++++ b/daemon/logger/awslogs/cloudwatchlogs_test.go +@@ -3,7 +3,6 @@ package awslogs // import "github.com/docker/docker/daemon/logger/awslogs" + import ( + "errors" + "fmt" +- "io/ioutil" + "net/http" + "net/http/httptest" + "os" +@@ -1669,7 +1668,7 @@ func TestNewAWSLogsClientCredentialSharedFile(t *testing.T) { + ` + content := []byte(contentStr) + +- tmpfile, err := ioutil.TempFile("", "example") ++ tmpfile, err := os.CreateTemp("", "example") + defer os.Remove(tmpfile.Name()) // clean up + assert.Check(t, err) + +diff --git a/daemon/logger/jsonfilelog/jsonfilelog_test.go b/daemon/logger/jsonfilelog/jsonfilelog_test.go +index de875832f2..3ccf1d1a96 100644 +--- a/daemon/logger/jsonfilelog/jsonfilelog_test.go ++++ b/daemon/logger/jsonfilelog/jsonfilelog_test.go +@@ -5,7 +5,7 @@ import ( + "compress/gzip" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "os" + "path/filepath" + "reflect" +@@ -22,7 +22,7 @@ import ( + + func TestJSONFileLogger(t *testing.T) { + cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657" +- tmp, err := ioutil.TempDir("", "docker-logger-") ++ tmp, err := os.MkdirTemp("", "docker-logger-") + if err != nil { + t.Fatal(err) + } +@@ -46,7 +46,7 @@ func TestJSONFileLogger(t *testing.T) { + if err := l.Log(&logger.Message{Line: []byte("line3"), Source: "src3"}); err != nil { + t.Fatal(err) + } +- res, err := ioutil.ReadFile(filename) ++ res, err := os.ReadFile(filename) + if err != nil { + t.Fatal(err) + } +@@ -63,7 +63,7 @@ func TestJSONFileLogger(t *testing.T) { + func TestJSONFileLoggerWithTags(t *testing.T) { + cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657" + cname := "test-container" +- tmp, err := ioutil.TempDir("", "docker-logger-") ++ tmp, err := os.MkdirTemp("", "docker-logger-") + + assert.NilError(t, err) + +@@ -90,7 +90,7 @@ func TestJSONFileLoggerWithTags(t *testing.T) { + err = l.Log(&logger.Message{Line: []byte("line3"), Source: "src3"}) + assert.NilError(t, err) + +- res, err := ioutil.ReadFile(filename) ++ res, err := os.ReadFile(filename) + assert.NilError(t, err) + + expected := `{"log":"line1\n","stream":"src1","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} +@@ -154,7 +154,7 @@ func BenchmarkJSONFileLoggerLog(b *testing.B) { + + func TestJSONFileLoggerWithOpts(t *testing.T) { + cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657" +- tmp, err := ioutil.TempDir("", "docker-logger-") ++ tmp, err := os.MkdirTemp("", "docker-logger-") + if err != nil { + t.Fatal(err) + } +@@ -176,12 +176,12 @@ func TestJSONFileLoggerWithOpts(t *testing.T) { + } + } + +- res, err := ioutil.ReadFile(filename) ++ res, err := os.ReadFile(filename) + if err != nil { + t.Fatal(err) + } + +- penUlt, err := ioutil.ReadFile(filename + ".1") ++ penUlt, err := os.ReadFile(filename + ".1") + if err != nil { + if !os.IsNotExist(err) { + t.Fatal(err) +@@ -197,7 +197,7 @@ func TestJSONFileLoggerWithOpts(t *testing.T) { + t.Fatal(err) + } + defer zipReader.Close() +- penUlt, err = ioutil.ReadAll(zipReader) ++ penUlt, err = io.ReadAll(zipReader) + if err != nil { + t.Fatal(err) + } +@@ -213,7 +213,7 @@ func TestJSONFileLoggerWithOpts(t *testing.T) { + t.Fatal(err) + } + defer zipReader.Close() +- antepenult, err := ioutil.ReadAll(zipReader) ++ antepenult, err := io.ReadAll(zipReader) + if err != nil { + t.Fatal(err) + } +@@ -271,7 +271,7 @@ func TestJSONFileLoggerWithOpts(t *testing.T) { + + func TestJSONFileLoggerWithLabelsEnv(t *testing.T) { + cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657" +- tmp, err := ioutil.TempDir("", "docker-logger-") ++ tmp, err := os.MkdirTemp("", "docker-logger-") + if err != nil { + t.Fatal(err) + } +@@ -292,7 +292,7 @@ func TestJSONFileLoggerWithLabelsEnv(t *testing.T) { + if err := l.Log(&logger.Message{Line: []byte("line"), Source: "src1"}); err != nil { + t.Fatal(err) + } +- res, err := ioutil.ReadFile(filename) ++ res, err := os.ReadFile(filename) + if err != nil { + t.Fatal(err) + } +diff --git a/daemon/logger/local/local_test.go b/daemon/logger/local/local_test.go +index d59a17df4f..ca31318499 100644 +--- a/daemon/logger/local/local_test.go ++++ b/daemon/logger/local/local_test.go +@@ -6,7 +6,6 @@ import ( + "encoding/binary" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "strings" +@@ -24,7 +23,7 @@ import ( + func TestWriteLog(t *testing.T) { + t.Parallel() + +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(dir) + +@@ -83,7 +82,7 @@ func TestWriteLog(t *testing.T) { + func TestReadLog(t *testing.T) { + t.Parallel() + +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(dir) + +@@ -170,7 +169,7 @@ func TestReadLog(t *testing.T) { + } + + func BenchmarkLogWrite(b *testing.B) { +- f, err := ioutil.TempFile("", b.Name()) ++ f, err := os.CreateTemp("", b.Name()) + assert.Assert(b, err) + defer os.Remove(f.Name()) + f.Close() +diff --git a/daemon/logger/local/read_test.go b/daemon/logger/local/read_test.go +index 21d8603649..4dd5f2043a 100644 +--- a/daemon/logger/local/read_test.go ++++ b/daemon/logger/local/read_test.go +@@ -2,7 +2,6 @@ package local + + import ( + "io" +- "io/ioutil" + "os" + "testing" + +@@ -23,7 +22,7 @@ func TestDecode(t *testing.T) { + } + + func testDecode(t *testing.T, buf []byte, split int) { +- fw, err := ioutil.TempFile("", t.Name()) ++ fw, err := os.CreateTemp("", t.Name()) + assert.NilError(t, err) + defer os.Remove(fw.Name()) + +diff --git a/daemon/logger/loggerutils/file_windows_test.go b/daemon/logger/loggerutils/file_windows_test.go +index 5b83753909..9978c94219 100644 +--- a/daemon/logger/loggerutils/file_windows_test.go ++++ b/daemon/logger/loggerutils/file_windows_test.go +@@ -1,7 +1,6 @@ + package loggerutils + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -10,7 +9,7 @@ import ( + ) + + func TestOpenFileDelete(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", t.Name()) ++ tmpDir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(tmpDir) + +@@ -22,7 +21,7 @@ func TestOpenFileDelete(t *testing.T) { + } + + func TestOpenFileRename(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", t.Name()) ++ tmpDir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(tmpDir) + +diff --git a/daemon/logger/loggerutils/logfile_test.go b/daemon/logger/loggerutils/logfile_test.go +index 7578b425d9..e816d782cf 100644 +--- a/daemon/logger/loggerutils/logfile_test.go ++++ b/daemon/logger/loggerutils/logfile_test.go +@@ -6,7 +6,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "strings" +@@ -116,7 +115,7 @@ func (dummyDecoder) Reset(io.Reader) {} + func TestFollowLogsConsumerGone(t *testing.T) { + lw := logger.NewLogWatcher() + +- f, err := ioutil.TempFile("", t.Name()) ++ f, err := os.CreateTemp("", t.Name()) + assert.NilError(t, err) + defer func() { + f.Close() +@@ -166,7 +165,7 @@ func TestFollowLogsProducerGone(t *testing.T) { + lw := logger.NewLogWatcher() + defer lw.ConsumerGone() + +- f, err := ioutil.TempFile("", t.Name()) ++ f, err := os.CreateTemp("", t.Name()) + assert.NilError(t, err) + defer os.Remove(f.Name()) + +@@ -248,11 +247,11 @@ func TestFollowLogsProducerGone(t *testing.T) { + } + + func TestCheckCapacityAndRotate(t *testing.T) { +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(dir) + +- f, err := ioutil.TempFile(dir, "log") ++ f, err := os.CreateTemp(dir, "log") + assert.NilError(t, err) + + l := &LogFile{ +@@ -337,7 +336,7 @@ type dirStringer struct { + } + + func (d dirStringer) String() string { +- ls, err := ioutil.ReadDir(d.d) ++ ls, err := os.ReadDir(d.d) + if err != nil { + return "" + } +@@ -347,7 +346,12 @@ func (d dirStringer) String() string { + + btw := bufio.NewWriter(tw) + +- for _, fi := range ls { ++ for _, entry := range ls { ++ fi, err := entry.Info() ++ if err != nil { ++ return "" ++ } ++ + btw.WriteString(fmt.Sprintf("%s\t%s\t%dB\t%s\n", fi.Name(), fi.Mode(), fi.Size(), fi.ModTime())) + } + btw.Flush() +diff --git a/daemon/logger/splunk/splunk.go b/daemon/logger/splunk/splunk.go +index 760a255003..5d76506dcb 100644 +--- a/daemon/logger/splunk/splunk.go ++++ b/daemon/logger/splunk/splunk.go +@@ -11,7 +11,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net/http" + "net/url" + "os" +@@ -185,7 +184,7 @@ func New(info logger.Info) (logger.Logger, error) { + + // If path to the root certificate is provided - load it + if caPath, ok := info.Config[splunkCAPathKey]; ok { +- caCert, err := ioutil.ReadFile(caPath) ++ caCert, err := os.ReadFile(caPath) + if err != nil { + return nil, err + } +@@ -531,12 +530,12 @@ func (l *splunkLogger) tryPostMessages(ctx context.Context, messages []*splunkMe + return err + } + defer func() { +- pools.Copy(ioutil.Discard, resp.Body) ++ pools.Copy(io.Discard, resp.Body) + resp.Body.Close() + }() + if resp.StatusCode != http.StatusOK { + rdr := io.LimitReader(resp.Body, maxResponseSize) +- body, err := ioutil.ReadAll(rdr) ++ body, err := io.ReadAll(rdr) + if err != nil { + return err + } +@@ -631,13 +630,13 @@ func verifySplunkConnection(l *splunkLogger) error { + return err + } + defer func() { +- pools.Copy(ioutil.Discard, resp.Body) ++ pools.Copy(io.Discard, resp.Body) + resp.Body.Close() + }() + + if resp.StatusCode != http.StatusOK { + rdr := io.LimitReader(resp.Body, maxResponseSize) +- body, err := ioutil.ReadAll(rdr) ++ body, err := io.ReadAll(rdr) + if err != nil { + return err + } +diff --git a/daemon/logger/splunk/splunkhecmock_test.go b/daemon/logger/splunk/splunkhecmock_test.go +index a3a83ac103..f592abe228 100644 +--- a/daemon/logger/splunk/splunkhecmock_test.go ++++ b/daemon/logger/splunk/splunkhecmock_test.go +@@ -6,7 +6,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net" + "net/http" + "sync" +@@ -150,7 +149,7 @@ func (hec *HTTPEventCollectorMock) ServeHTTP(writer http.ResponseWriter, request + + // Read body + var body []byte +- body, err = ioutil.ReadAll(reader) ++ body, err = io.ReadAll(reader) + if err != nil { + hec.test.Fatal(err) + } +diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go +index a5a5acfdc0..7b9a5dd03e 100644 +--- a/daemon/oci_linux.go ++++ b/daemon/oci_linux.go +@@ -3,7 +3,6 @@ package daemon // import "github.com/docker/docker/daemon" + import ( + "context" + "fmt" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -98,7 +97,7 @@ func WithRootless(daemon *Daemon) coci.SpecOpts { + return errors.New("$ROOTLESSKIT_PARENT_EUID is not set (requires RootlessKit v0.8.0)") + } + controllersPath := fmt.Sprintf("/sys/fs/cgroup/user.slice/user-%s.slice/cgroup.controllers", rootlesskitParentEUID) +- controllersFile, err := ioutil.ReadFile(controllersPath) ++ controllersFile, err := os.ReadFile(controllersPath) + if err != nil { + return err + } +diff --git a/daemon/oci_linux_test.go b/daemon/oci_linux_test.go +index 32854f9215..37d3cb3589 100644 +--- a/daemon/oci_linux_test.go ++++ b/daemon/oci_linux_test.go +@@ -1,7 +1,6 @@ + package daemon // import "github.com/docker/docker/daemon" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -19,7 +18,7 @@ import ( + ) + + func setupFakeDaemon(t *testing.T, c *container.Container) *Daemon { +- root, err := ioutil.TempDir("", "oci_linux_test-root") ++ root, err := os.MkdirTemp("", "oci_linux_test-root") + assert.NilError(t, err) + + rootfs := filepath.Join(root, "rootfs") +diff --git a/daemon/oci_windows.go b/daemon/oci_windows.go +index 16054f356c..c968d10edf 100644 +--- a/daemon/oci_windows.go ++++ b/daemon/oci_windows.go +@@ -3,7 +3,7 @@ package daemon // import "github.com/docker/docker/daemon" + import ( + "encoding/json" + "fmt" +- "io/ioutil" ++ "os" + "path/filepath" + "runtime" + "strings" +@@ -514,7 +514,7 @@ func readCredentialSpecFile(id, root, location string) (string, error) { + if !strings.HasPrefix(full, base) { + return "", fmt.Errorf("invalid credential spec - file:// path must be under %s", base) + } +- bcontents, err := ioutil.ReadFile(full) ++ bcontents, err := os.ReadFile(full) + if err != nil { + return "", errors.Wrapf(err, "credential spec for container %s could not be read from file %q", id, full) + } +diff --git a/daemon/oci_windows_test.go b/daemon/oci_windows_test.go +index 14351a3b87..5503eff813 100644 +--- a/daemon/oci_windows_test.go ++++ b/daemon/oci_windows_test.go +@@ -2,7 +2,6 @@ package daemon + + import ( + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "strings" +@@ -70,7 +69,7 @@ func TestSetWindowsCredentialSpecInSpec(t *testing.T) { + assert.NilError(t, err) + dummyCredFileName := "dummy-cred-spec.json" + dummyCredFilePath := filepath.Join(credSpecsDir, dummyCredFileName) +- err = ioutil.WriteFile(dummyCredFilePath, []byte(dummyCredFileContents), 0644) ++ err = os.WriteFile(dummyCredFilePath, []byte(dummyCredFileContents), 0644) + defer func() { + assert.NilError(t, os.Remove(dummyCredFilePath)) + }() +diff --git a/daemon/runtime_unix.go b/daemon/runtime_unix.go +index c5903cbcf7..1478735b83 100644 +--- a/daemon/runtime_unix.go ++++ b/daemon/runtime_unix.go +@@ -5,7 +5,6 @@ package daemon + + import ( + "fmt" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -102,7 +101,7 @@ func (daemon *Daemon) initRuntimes(runtimes map[string]types.Runtime) (err error + if len(rt.Args) > 0 { + script := filepath.Join(tmpDir, name) + content := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", rt.Path, strings.Join(rt.Args, " ")) +- if err := ioutil.WriteFile(script, []byte(content), 0700); err != nil { ++ if err := os.WriteFile(script, []byte(content), 0700); err != nil { + return err + } + } +diff --git a/daemon/trustkey_test.go b/daemon/trustkey_test.go +index 95e15780f9..b30c2ebeae 100644 +--- a/daemon/trustkey_test.go ++++ b/daemon/trustkey_test.go +@@ -1,7 +1,6 @@ + package daemon // import "github.com/docker/docker/daemon" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -13,11 +12,11 @@ import ( + + // LoadOrCreateTrustKey + func TestLoadOrCreateTrustKeyInvalidKeyFile(t *testing.T) { +- tmpKeyFolderPath, err := ioutil.TempDir("", "api-trustkey-test") ++ tmpKeyFolderPath, err := os.MkdirTemp("", "api-trustkey-test") + assert.NilError(t, err) + defer os.RemoveAll(tmpKeyFolderPath) + +- tmpKeyFile, err := ioutil.TempFile(tmpKeyFolderPath, "keyfile") ++ tmpKeyFile, err := os.CreateTemp(tmpKeyFolderPath, "keyfile") + assert.NilError(t, err) + + _, err = loadOrCreateTrustKey(tmpKeyFile.Name()) +diff --git a/distribution/manifest.go b/distribution/manifest.go +index 169e703343..8d528a4906 100644 +--- a/distribution/manifest.go ++++ b/distribution/manifest.go +@@ -5,7 +5,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "strings" + + "github.com/containerd/containerd/content" +@@ -141,7 +140,7 @@ func (m *manifestStore) getLocal(ctx context.Context, desc specs.Descriptor, ref + } + + r := io.NewSectionReader(ra, 0, ra.Size()) +- data, err := ioutil.ReadAll(r) ++ data, err := io.ReadAll(r) + if err != nil { + return nil, errors.Wrap(err, "error reading manifest from content store") + } +diff --git a/distribution/manifest_test.go b/distribution/manifest_test.go +index 7d53257e3c..b3ee8e7a38 100644 +--- a/distribution/manifest_test.go ++++ b/distribution/manifest_test.go +@@ -3,7 +3,6 @@ package distribution + import ( + "context" + "encoding/json" +- "io/ioutil" + "os" + "strings" + "sync" +@@ -135,7 +134,7 @@ func TestManifestStore(t *testing.T) { + dgst := digest.Canonical.FromBytes(serialized) + + setupTest := func(t *testing.T) (reference.Named, specs.Descriptor, *mockManifestGetter, *manifestStore, content.Store, func(*testing.T)) { +- root, err := ioutil.TempDir("", strings.Replace(t.Name(), "/", "_", -1)) ++ root, err := os.MkdirTemp("", strings.Replace(t.Name(), "/", "_", -1)) + assert.NilError(t, err) + defer func() { + if t.Failed() { +diff --git a/distribution/metadata/metadata.go b/distribution/metadata/metadata.go +index 4ae8223bd0..88c859572d 100644 +--- a/distribution/metadata/metadata.go ++++ b/distribution/metadata/metadata.go +@@ -1,7 +1,6 @@ + package metadata // import "github.com/docker/docker/distribution/metadata" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "sync" +@@ -48,7 +47,7 @@ func (store *FSMetadataStore) Get(namespace string, key string) ([]byte, error) + store.RLock() + defer store.RUnlock() + +- return ioutil.ReadFile(store.path(namespace, key)) ++ return os.ReadFile(store.path(namespace, key)) + } + + // Set writes data indexed by namespace and key. The data is written to a file +diff --git a/distribution/metadata/v1_id_service_test.go b/distribution/metadata/v1_id_service_test.go +index 1fb0459fb4..a548733e15 100644 +--- a/distribution/metadata/v1_id_service_test.go ++++ b/distribution/metadata/v1_id_service_test.go +@@ -1,7 +1,6 @@ + package metadata // import "github.com/docker/docker/distribution/metadata" + + import ( +- "io/ioutil" + "os" + "testing" + +@@ -10,7 +9,7 @@ import ( + ) + + func TestV1IDService(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "v1-id-service-test") ++ tmpDir, err := os.MkdirTemp("", "v1-id-service-test") + if err != nil { + t.Fatalf("could not create temp dir: %v", err) + } +diff --git a/distribution/metadata/v2_metadata_service_test.go b/distribution/metadata/v2_metadata_service_test.go +index c5f0a562ae..ca54eaed98 100644 +--- a/distribution/metadata/v2_metadata_service_test.go ++++ b/distribution/metadata/v2_metadata_service_test.go +@@ -2,7 +2,6 @@ package metadata // import "github.com/docker/docker/distribution/metadata" + + import ( + "encoding/hex" +- "io/ioutil" + "math/rand" + "os" + "reflect" +@@ -13,7 +12,7 @@ import ( + ) + + func TestV2MetadataService(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "blobsum-storage-service-test") ++ tmpDir, err := os.MkdirTemp("", "blobsum-storage-service-test") + if err != nil { + t.Fatalf("could not create temp dir: %v", err) + } +diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go +index 5883de9566..9ce108f547 100644 +--- a/distribution/pull_v2.go ++++ b/distribution/pull_v2.go +@@ -5,7 +5,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net/url" + "os" + "runtime" +@@ -1112,7 +1111,7 @@ func fixManifestLayers(m *schema1.Manifest) error { + } + + func createDownloadFile() (*os.File, error) { +- return ioutil.TempFile("", "GetImageBlob") ++ return os.CreateTemp("", "GetImageBlob") + } + + func toOCIPlatform(p manifestlist.PlatformSpec) specs.Platform { +diff --git a/distribution/pull_v2_test.go b/distribution/pull_v2_test.go +index e4cb43ba82..1eaa265005 100644 +--- a/distribution/pull_v2_test.go ++++ b/distribution/pull_v2_test.go +@@ -4,10 +4,10 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" ++ "os" + "reflect" + "regexp" + "runtime" +@@ -134,7 +134,7 @@ func TestValidateManifest(t *testing.T) { + + // Good manifest + +- goodManifestBytes, err := ioutil.ReadFile("fixtures/validate_manifest/good_manifest") ++ goodManifestBytes, err := os.ReadFile("fixtures/validate_manifest/good_manifest") + if err != nil { + t.Fatal("error reading fixture:", err) + } +@@ -156,7 +156,7 @@ func TestValidateManifest(t *testing.T) { + + // "Extra data" manifest + +- extraDataManifestBytes, err := ioutil.ReadFile("fixtures/validate_manifest/extra_data_manifest") ++ extraDataManifestBytes, err := os.ReadFile("fixtures/validate_manifest/extra_data_manifest") + if err != nil { + t.Fatal("error reading fixture:", err) + } +@@ -178,7 +178,7 @@ func TestValidateManifest(t *testing.T) { + + // Bad manifest + +- badManifestBytes, err := ioutil.ReadFile("fixtures/validate_manifest/bad_manifest") ++ badManifestBytes, err := os.ReadFile("fixtures/validate_manifest/bad_manifest") + if err != nil { + t.Fatal("error reading fixture:", err) + } +diff --git a/distribution/xfer/download_test.go b/distribution/xfer/download_test.go +index 7ad8d89c5f..0174177412 100644 +--- a/distribution/xfer/download_test.go ++++ b/distribution/xfer/download_test.go +@@ -6,7 +6,6 @@ import ( + "errors" + "fmt" + "io" +- "io/ioutil" + "runtime" + "sync/atomic" + "testing" +@@ -30,7 +29,7 @@ type mockLayer struct { + } + + func (ml *mockLayer) TarStream() (io.ReadCloser, error) { +- return ioutil.NopCloser(bytes.NewBuffer(ml.layerData.Bytes())), nil ++ return io.NopCloser(bytes.NewBuffer(ml.layerData.Bytes())), nil + } + + func (ml *mockLayer) TarStreamFrom(layer.ChainID) (io.ReadCloser, error) { +@@ -192,7 +191,7 @@ func (d *mockDownloadDescriptor) mockTarStream() io.ReadCloser { + // The mock implementation returns the ID repeated 5 times as a tar + // stream instead of actual tar data. The data is ignored except for + // computing IDs. +- return ioutil.NopCloser(bytes.NewBuffer([]byte(d.id + d.id + d.id + d.id + d.id))) ++ return io.NopCloser(bytes.NewBuffer([]byte(d.id + d.id + d.id + d.id + d.id))) + } + + // Download is called to perform the download. +diff --git a/image/fs.go b/image/fs.go +index 8300c41884..d996501cc6 100644 +--- a/image/fs.go ++++ b/image/fs.go +@@ -2,7 +2,6 @@ package image // import "github.com/docker/docker/image" + + import ( + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "sync" +@@ -68,7 +67,7 @@ func (s *fs) metadataDir(dgst digest.Digest) string { + func (s *fs) Walk(f DigestWalkFunc) error { + // Only Canonical digest (sha256) is currently supported + s.RLock() +- dir, err := ioutil.ReadDir(filepath.Join(s.root, contentDirName, string(digest.Canonical))) ++ dir, err := os.ReadDir(filepath.Join(s.root, contentDirName, string(digest.Canonical))) + s.RUnlock() + if err != nil { + return err +@@ -95,7 +94,7 @@ func (s *fs) Get(dgst digest.Digest) ([]byte, error) { + } + + func (s *fs) get(dgst digest.Digest) ([]byte, error) { +- content, err := ioutil.ReadFile(s.contentFile(dgst)) ++ content, err := os.ReadFile(s.contentFile(dgst)) + if err != nil { + return nil, errors.Wrapf(err, "failed to get digest %s", dgst) + } +@@ -159,7 +158,7 @@ func (s *fs) GetMetadata(dgst digest.Digest, key string) ([]byte, error) { + if _, err := s.get(dgst); err != nil { + return nil, err + } +- bytes, err := ioutil.ReadFile(filepath.Join(s.metadataDir(dgst), key)) ++ bytes, err := os.ReadFile(filepath.Join(s.metadataDir(dgst), key)) + if err != nil { + return nil, errors.Wrap(err, "failed to read metadata") + } +diff --git a/image/fs_test.go b/image/fs_test.go +index 6bf6c2f4ad..dc2f52cc38 100644 +--- a/image/fs_test.go ++++ b/image/fs_test.go +@@ -5,7 +5,6 @@ import ( + "crypto/sha256" + "encoding/hex" + "errors" +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -16,7 +15,7 @@ import ( + ) + + func defaultFSStoreBackend(t *testing.T) (StoreBackend, func()) { +- tmpdir, err := ioutil.TempDir("", "images-fs-store") ++ tmpdir, err := os.MkdirTemp("", "images-fs-store") + assert.Check(t, err) + + fsBackend, err := NewFSStoreBackend(tmpdir) +@@ -32,7 +31,7 @@ func TestFSGetInvalidData(t *testing.T) { + dgst, err := store.Set([]byte("foobar")) + assert.Check(t, err) + +- err = ioutil.WriteFile(filepath.Join(store.(*fs).root, contentDirName, string(dgst.Algorithm()), dgst.Hex()), []byte("foobar2"), 0600) ++ err = os.WriteFile(filepath.Join(store.(*fs).root, contentDirName, string(dgst.Algorithm()), dgst.Hex()), []byte("foobar2"), 0600) + assert.Check(t, err) + + _, err = store.Get(dgst) +@@ -52,7 +51,7 @@ func TestFSInvalidSet(t *testing.T) { + } + + func TestFSInvalidRoot(t *testing.T) { +- tmpdir, err := ioutil.TempDir("", "images-fs-store") ++ tmpdir, err := os.MkdirTemp("", "images-fs-store") + assert.Check(t, err) + defer os.RemoveAll(tmpdir) + +@@ -130,7 +129,7 @@ func TestFSInvalidWalker(t *testing.T) { + fooID, err := store.Set([]byte("foo")) + assert.Check(t, err) + +- err = ioutil.WriteFile(filepath.Join(store.(*fs).root, contentDirName, "sha256/foobar"), []byte("foobar"), 0600) ++ err = os.WriteFile(filepath.Join(store.(*fs).root, contentDirName, "sha256/foobar"), []byte("foobar"), 0600) + assert.Check(t, err) + + n := 0 +diff --git a/image/tarexport/load.go b/image/tarexport/load.go +index bbbb238b2b..3ededcbffb 100644 +--- a/image/tarexport/load.go ++++ b/image/tarexport/load.go +@@ -5,7 +5,6 @@ import ( + "errors" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "reflect" +@@ -35,7 +34,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool) + } + outStream = streamformatter.NewStdoutWriter(outStream) + +- tmpDir, err := ioutil.TempDir("", "docker-import-") ++ tmpDir, err := os.MkdirTemp("", "docker-import-") + if err != nil { + return err + } +@@ -72,7 +71,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool) + if err != nil { + return err + } +- config, err := ioutil.ReadFile(configPath) ++ config, err := os.ReadFile(configPath) + if err != nil { + return err + } +@@ -227,7 +226,7 @@ func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer, progressOut + + legacyLoadedMap := make(map[string]image.ID) + +- dirs, err := ioutil.ReadDir(tmpDir) ++ dirs, err := os.ReadDir(tmpDir) + if err != nil { + return err + } +@@ -286,7 +285,7 @@ func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[str + if err != nil { + return err + } +- imageJSON, err := ioutil.ReadFile(configPath) ++ imageJSON, err := os.ReadFile(configPath) + if err != nil { + logrus.Debugf("Error reading json: %v", err) + return err +diff --git a/image/tarexport/save.go b/image/tarexport/save.go +index 0fb5986b72..285f998a9b 100644 +--- a/image/tarexport/save.go ++++ b/image/tarexport/save.go +@@ -4,7 +4,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -189,7 +188,7 @@ func (s *saveSession) save(outStream io.Writer) error { + s.diffIDPaths = make(map[layer.DiffID]string) + + // get image json +- tempDir, err := ioutil.TempDir("", "docker-export-") ++ tempDir, err := os.MkdirTemp("", "docker-export-") + if err != nil { + return err + } +@@ -337,7 +336,7 @@ func (s *saveSession) saveImage(id image.ID) (map[layer.DiffID]distribution.Desc + } + + configFile := filepath.Join(s.outDir, id.Digest().Hex()+".json") +- if err := ioutil.WriteFile(configFile, img.RawJSON(), 0644); err != nil { ++ if err := os.WriteFile(configFile, img.RawJSON(), 0644); err != nil { + return nil, err + } + if err := system.Chtimes(configFile, img.Created, img.Created); err != nil { +@@ -359,7 +358,7 @@ func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, creat + } + + // todo: why is this version file here? +- if err := ioutil.WriteFile(filepath.Join(outDir, legacyVersionFileName), []byte("1.0"), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(outDir, legacyVersionFileName), []byte("1.0"), 0644); err != nil { + return distribution.Descriptor{}, err + } + +@@ -368,7 +367,7 @@ func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, creat + return distribution.Descriptor{}, err + } + +- if err := ioutil.WriteFile(filepath.Join(outDir, legacyConfigFileName), imageConfig, 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(outDir, legacyConfigFileName), imageConfig, 0644); err != nil { + return distribution.Descriptor{}, err + } + +diff --git a/integration-cli/benchmark_test.go b/integration-cli/benchmark_test.go +index e86e9fc6e6..8ab87b22d9 100644 +--- a/integration-cli/benchmark_test.go ++++ b/integration-cli/benchmark_test.go +@@ -2,7 +2,6 @@ package main + + import ( + "fmt" +- "io/ioutil" + "os" + "runtime" + "strings" +@@ -37,7 +36,7 @@ func (s *DockerSuite) BenchmarkConcurrentContainerActions(c *testing.B) { + } + + id := strings.TrimSpace(out) +- tmpDir, err := ioutil.TempDir("", "docker-concurrent-test-"+id) ++ tmpDir, err := os.MkdirTemp("", "docker-concurrent-test-"+id) + if err != nil { + chErr <- err + return +diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go +index 84ced20e76..9a710b5210 100644 +--- a/integration-cli/check_test.go ++++ b/integration-cli/check_test.go +@@ -4,7 +4,6 @@ import ( + "context" + "flag" + "fmt" +- "io/ioutil" + "net/http/httptest" + "os" + "path" +@@ -151,7 +150,7 @@ func (s *DockerSuite) OnTimeout(c *testing.T) { + return + } + path := filepath.Join(os.Getenv("DEST"), "docker.pid") +- b, err := ioutil.ReadFile(path) ++ b, err := os.ReadFile(path) + if err != nil { + c.Fatalf("Failed to get daemon PID from %s\n", path) + } +diff --git a/integration-cli/docker_api_build_test.go b/integration-cli/docker_api_build_test.go +index e23de015ad..507ebe624c 100644 +--- a/integration-cli/docker_api_build_test.go ++++ b/integration-cli/docker_api_build_test.go +@@ -7,7 +7,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net/http" + "regexp" + "strings" +@@ -226,7 +225,7 @@ func (s *DockerSuite) TestBuildAPIUnnormalizedTarPaths(c *testing.T) { + + assert.NilError(c, tw.Close(), "failed to close tar archive") + +- res, body, err := request.Post("/build", request.RawContent(ioutil.NopCloser(buffer)), request.ContentType("application/x-tar")) ++ res, body, err := request.Post("/build", request.RawContent(io.NopCloser(buffer)), request.ContentType("application/x-tar")) + assert.NilError(c, err) + assert.Equal(c, res.StatusCode, http.StatusOK) + +@@ -326,7 +325,7 @@ func (s *DockerRegistrySuite) TestBuildCopyFromForcePull(c *testing.T) { + // push the image to the registry + rc, err := client.ImagePush(context.TODO(), repoName, types.ImagePushOptions{RegistryAuth: "{}"}) + assert.Check(c, err) +- _, err = io.Copy(ioutil.Discard, rc) ++ _, err = io.Copy(io.Discard, rc) + assert.Check(c, err) + + dockerfile := fmt.Sprintf(` +diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go +index 76ce061e7d..75af8fe2d2 100644 +--- a/integration-cli/docker_api_containers_test.go ++++ b/integration-cli/docker_api_containers_test.go +@@ -7,7 +7,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net/http" + "os" + "path/filepath" +@@ -282,7 +281,7 @@ func (s *DockerSuite) TestGetContainerStatsStream(c *testing.T) { + case <-time.After(2 * time.Second): + c.Fatal("stream was not closed after container was removed") + case sr := <-bc: +- b, err := ioutil.ReadAll(sr.stats.Body) ++ b, err := io.ReadAll(sr.stats.Body) + defer sr.stats.Body.Close() + assert.NilError(c, err) + s := string(b) +@@ -324,7 +323,7 @@ func (s *DockerSuite) TestGetContainerStatsNoStream(c *testing.T) { + case <-time.After(2 * time.Second): + c.Fatal("stream was not closed after container was removed") + case sr := <-bc: +- b, err := ioutil.ReadAll(sr.stats.Body) ++ b, err := io.ReadAll(sr.stats.Body) + defer sr.stats.Body.Close() + assert.NilError(c, err) + s := string(b) +@@ -656,7 +655,7 @@ func (s *DockerSuite) TestContainerAPIVerifyHeader(c *testing.T) { + create := func(ct string) (*http.Response, io.ReadCloser, error) { + jsonData := bytes.NewBuffer(nil) + assert.Assert(c, json.NewEncoder(jsonData).Encode(config) == nil) +- return request.Post("/containers/create", request.RawContent(ioutil.NopCloser(jsonData)), request.ContentType(ct)) ++ return request.Post("/containers/create", request.RawContent(io.NopCloser(jsonData)), request.ContentType(ct)) + } + + // Try with no content-type +@@ -1940,10 +1939,10 @@ func (s *DockerSuite) TestContainerAPICreateMountsBindRead(c *testing.T) { + // also with data in the host side + prefix, slash := getPrefixAndSlashFromDaemonPlatform() + destPath := prefix + slash + "foo" +- tmpDir, err := ioutil.TempDir("", "test-mounts-api-bind") ++ tmpDir, err := os.MkdirTemp("", "test-mounts-api-bind") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir) +- err = ioutil.WriteFile(filepath.Join(tmpDir, "bar"), []byte("hello"), 0666) ++ err = os.WriteFile(filepath.Join(tmpDir, "bar"), []byte("hello"), 0666) + assert.NilError(c, err) + config := containertypes.Config{ + Image: "busybox", +@@ -2026,7 +2025,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsCreate(c *testing.T) { + + if testEnv.IsLocalDaemon() { + // setup temp dir for testing binds +- tmpDir1, err := ioutil.TempDir("", "test-mounts-api-1") ++ tmpDir1, err := os.MkdirTemp("", "test-mounts-api-1") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir1) + cases = append(cases, []testCase{ +@@ -2231,7 +2230,7 @@ func (s *DockerSuite) TestContainerKillCustomStopSignal(c *testing.T) { + assert.NilError(c, err) + defer res.Body.Close() + +- b, err := ioutil.ReadAll(res.Body) ++ b, err := io.ReadAll(res.Body) + assert.NilError(c, err) + assert.Equal(c, res.StatusCode, http.StatusNoContent, string(b)) + err = waitInspect(id, "{{.State.Running}} {{.State.Restarting}}", "false false", 30*time.Second) +diff --git a/integration-cli/docker_api_containers_windows_test.go b/integration-cli/docker_api_containers_windows_test.go +index f1891ebe4e..cfb1596c13 100644 +--- a/integration-cli/docker_api_containers_windows_test.go ++++ b/integration-cli/docker_api_containers_windows_test.go +@@ -6,7 +6,7 @@ package main + import ( + "context" + "fmt" +- "io/ioutil" ++ "io" + "math/rand" + "strings" + "testing" +@@ -41,7 +41,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *testing.T) { + go func() { + conn, err := l.Accept() + if err == nil { +- b, err = ioutil.ReadAll(conn) ++ b, err = io.ReadAll(conn) + conn.Close() + } + ch <- err +diff --git a/integration-cli/docker_api_exec_test.go b/integration-cli/docker_api_exec_test.go +index 02b33ac0fb..3bf5d003f8 100644 +--- a/integration-cli/docker_api_exec_test.go ++++ b/integration-cli/docker_api_exec_test.go +@@ -5,7 +5,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "os" + "strings" +@@ -47,7 +47,7 @@ func (s *DockerSuite) TestExecAPICreateNoValidContentType(c *testing.T) { + c.Fatalf("Can not encode data to json %s", err) + } + +- res, body, err := request.Post(fmt.Sprintf("/containers/%s/exec", name), request.RawContent(ioutil.NopCloser(jsonData)), request.ContentType("test/plain")) ++ res, body, err := request.Post(fmt.Sprintf("/containers/%s/exec", name), request.RawContent(io.NopCloser(jsonData)), request.ContentType("test/plain")) + assert.NilError(c, err) + if versions.LessThan(testEnv.DaemonAPIVersion(), "1.32") { + assert.Equal(c, res.StatusCode, http.StatusInternalServerError) +@@ -217,12 +217,12 @@ func (s *DockerSuite) TestExecStateCleanup(c *testing.T) { + stateDir := "/var/run/docker/containerd/" + cid + + checkReadDir := func(c *testing.T) (interface{}, string) { +- fi, err := ioutil.ReadDir(stateDir) ++ fi, err := os.ReadDir(stateDir) + assert.NilError(c, err) + return len(fi), "" + } + +- fi, err := ioutil.ReadDir(stateDir) ++ fi, err := os.ReadDir(stateDir) + assert.NilError(c, err) + assert.Assert(c, len(fi) > 1) + +@@ -251,7 +251,7 @@ func createExec(c *testing.T, name string) string { + func createExecCmd(c *testing.T, name string, cmd string) string { + _, reader, err := request.Post(fmt.Sprintf("/containers/%s/exec", name), request.JSONBody(map[string]interface{}{"Cmd": []string{cmd}})) + assert.NilError(c, err) +- b, err := ioutil.ReadAll(reader) ++ b, err := io.ReadAll(reader) + assert.NilError(c, err) + defer reader.Close() + createResp := struct { +diff --git a/integration-cli/docker_api_logs_test.go b/integration-cli/docker_api_logs_test.go +index b068144279..e4a845e70f 100644 +--- a/integration-cli/docker_api_logs_test.go ++++ b/integration-cli/docker_api_logs_test.go +@@ -6,7 +6,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "net/http" + "strconv" + "strings" +@@ -173,7 +172,7 @@ func (s *DockerSuite) TestLogsAPIUntil(c *testing.T) { + assert.NilError(c, err) + + actualStdout := new(bytes.Buffer) +- actualStderr := ioutil.Discard ++ actualStderr := io.Discard + _, err = stdcopy.StdCopy(actualStdout, actualStderr, reader) + assert.NilError(c, err) + +@@ -210,7 +209,7 @@ func (s *DockerSuite) TestLogsAPIUntilDefaultValue(c *testing.T) { + assert.NilError(c, err) + + actualStdout := new(bytes.Buffer) +- actualStderr := ioutil.Discard ++ actualStderr := io.Discard + _, err = stdcopy.StdCopy(actualStdout, actualStderr, reader) + assert.NilError(c, err) + +diff --git a/integration-cli/docker_api_swarm_test.go b/integration-cli/docker_api_swarm_test.go +index b374b9c4ce..441f7a1652 100644 +--- a/integration-cli/docker_api_swarm_test.go ++++ b/integration-cli/docker_api_swarm_test.go +@@ -6,9 +6,9 @@ package main + import ( + "context" + "fmt" +- "io/ioutil" + "net" + "net/http" ++ "os" + "path/filepath" + "runtime" + "strings" +@@ -224,7 +224,7 @@ func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *testing.T) { + // while waiting for the role to change to worker, and the test can + // time out during this interval. + poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) { +- certBytes, err := ioutil.ReadFile(filepath.Join(d2.Folder, "root", "swarm", "certificates", "swarm-node.crt")) ++ certBytes, err := os.ReadFile(filepath.Join(d2.Folder, "root", "swarm", "certificates", "swarm-node.crt")) + if err != nil { + return "", fmt.Sprintf("error: %v", err) + } +diff --git a/integration-cli/docker_api_test.go b/integration-cli/docker_api_test.go +index e86b4298ea..6a091bc8a4 100644 +--- a/integration-cli/docker_api_test.go ++++ b/integration-cli/docker_api_test.go +@@ -2,7 +2,7 @@ package main + + import ( + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "runtime" + "strconv" +@@ -52,7 +52,7 @@ func (s *DockerSuite) TestAPIClientVersionOldNotSupported(c *testing.T) { + defer body.Close() + assert.Equal(c, resp.StatusCode, http.StatusBadRequest) + expected := fmt.Sprintf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", version, api.MinVersion) +- content, err := ioutil.ReadAll(body) ++ content, err := io.ReadAll(body) + assert.NilError(c, err) + assert.Equal(c, strings.TrimSpace(string(content)), expected) + } +diff --git a/integration-cli/docker_cli_attach_unix_test.go b/integration-cli/docker_cli_attach_unix_test.go +index ca51d8ce29..8dbb55e761 100644 +--- a/integration-cli/docker_cli_attach_unix_test.go ++++ b/integration-cli/docker_cli_attach_unix_test.go +@@ -5,7 +5,7 @@ package main + + import ( + "bufio" +- "io/ioutil" ++ "io" + "os/exec" + "strings" + "testing" +@@ -51,7 +51,7 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *testing.T) { + select { + case err := <-errChan: + tty.Close() +- out, _ := ioutil.ReadAll(pty) ++ out, _ := io.ReadAll(pty) + assert.Assert(c, err == nil, "out: %v", string(out)) + case <-time.After(attachWait): + c.Fatal("timed out without attach returning") +diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go +index 968e1d67a0..34f61b450f 100644 +--- a/integration-cli/docker_cli_build_test.go ++++ b/integration-cli/docker_cli_build_test.go +@@ -5,7 +5,6 @@ import ( + "bytes" + "encoding/json" + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "reflect" +@@ -939,7 +938,7 @@ func (s *DockerSuite) TestBuildAddBadLinks(c *testing.T) { + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(dockerfile)) + defer ctx.Close() + +- tempDir, err := ioutil.TempDir("", "test-link-absolute-temp-") ++ tempDir, err := os.MkdirTemp("", "test-link-absolute-temp-") + if err != nil { + c.Fatalf("failed to create temporary directory: %s", tempDir) + } +@@ -1015,7 +1014,7 @@ func (s *DockerSuite) TestBuildAddBadLinksVolume(c *testing.T) { + targetFile = "foo.txt" + ) + +- tempDir, err := ioutil.TempDir("", "test-link-absolute-volume-temp-") ++ tempDir, err := os.MkdirTemp("", "test-link-absolute-volume-temp-") + if err != nil { + c.Fatalf("failed to create temporary directory: %s", tempDir) + } +@@ -1514,7 +1513,7 @@ func (s *DockerSuite) TestBuildContextCleanup(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon) + + name := "testbuildcontextcleanup" +- entries, err := ioutil.ReadDir(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "tmp")) ++ entries, err := os.ReadDir(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "tmp")) + if err != nil { + c.Fatalf("failed to list contents of tmp dir: %s", err) + } +@@ -1522,7 +1521,7 @@ func (s *DockerSuite) TestBuildContextCleanup(c *testing.T) { + buildImageSuccessfully(c, name, build.WithDockerfile(`FROM `+minimalBaseImage()+` + ENTRYPOINT ["/bin/echo"]`)) + +- entriesFinal, err := ioutil.ReadDir(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "tmp")) ++ entriesFinal, err := os.ReadDir(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "tmp")) + if err != nil { + c.Fatalf("failed to list contents of tmp dir: %s", err) + } +@@ -1536,7 +1535,7 @@ func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon) + + name := "testbuildcontextcleanup" +- entries, err := ioutil.ReadDir(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "tmp")) ++ entries, err := os.ReadDir(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "tmp")) + if err != nil { + c.Fatalf("failed to list contents of tmp dir: %s", err) + } +@@ -1546,7 +1545,7 @@ func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *testing.T) { + ExitCode: 1, + }) + +- entriesFinal, err := ioutil.ReadDir(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "tmp")) ++ entriesFinal, err := os.ReadDir(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "tmp")) + if err != nil { + c.Fatalf("failed to list contents of tmp dir: %s", err) + } +@@ -1556,9 +1555,9 @@ func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *testing.T) { + + } + +-// compareDirectoryEntries compares two sets of FileInfo (usually taken from a directory) ++// compareDirectoryEntries compares two sets of DirEntry (usually taken from a directory) + // and returns an error if different. +-func compareDirectoryEntries(e1 []os.FileInfo, e2 []os.FileInfo) error { ++func compareDirectoryEntries(e1 []os.DirEntry, e2 []os.DirEntry) error { + var ( + e1Entries = make(map[string]struct{}) + e2Entries = make(map[string]struct{}) +@@ -2068,9 +2067,9 @@ func (s *DockerSuite) TestBuildNoContext(c *testing.T) { + // FIXME(vdemeester) migrate to docker/cli e2e + func (s *DockerSuite) TestBuildDockerfileStdin(c *testing.T) { + name := "stdindockerfile" +- tmpDir, err := ioutil.TempDir("", "fake-context") ++ tmpDir, err := os.MkdirTemp("", "fake-context") + assert.NilError(c, err) +- err = ioutil.WriteFile(filepath.Join(tmpDir, "foo"), []byte("bar"), 0600) ++ err = os.WriteFile(filepath.Join(tmpDir, "foo"), []byte("bar"), 0600) + assert.NilError(c, err) + + icmd.RunCmd(icmd.Cmd{ +@@ -2110,12 +2109,12 @@ func (s *DockerSuite) TestBuildDockerfileStdinDockerignoreIgnored(c *testing.T) + + func (s *DockerSuite) testBuildDockerfileStdinNoExtraFiles(c *testing.T, hasDockerignore, ignoreDockerignore bool) { + name := "stdindockerfilenoextra" +- tmpDir, err := ioutil.TempDir("", "fake-context") ++ tmpDir, err := os.MkdirTemp("", "fake-context") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir) + + writeFile := func(filename, content string) { +- err = ioutil.WriteFile(filepath.Join(tmpDir, filename), []byte(content), 0600) ++ err = os.WriteFile(filepath.Join(tmpDir, filename), []byte(content), 0600) + assert.NilError(c, err) + } + +@@ -2845,7 +2844,7 @@ ADD test.tar /existing-directory + RUN cat /existing-directory/test/foo | grep Hi + ADD test.tar /existing-directory-trailing-slash/ + RUN cat /existing-directory-trailing-slash/test/foo | grep Hi` +- tmpDir, err := ioutil.TempDir("", "fake-context") ++ tmpDir, err := os.MkdirTemp("", "fake-context") + assert.NilError(c, err) + testTar, err := os.Create(filepath.Join(tmpDir, "test.tar")) + if err != nil { +@@ -2868,7 +2867,7 @@ RUN cat /existing-directory-trailing-slash/test/foo | grep Hi` + c.Fatalf("failed to close tar archive: %v", err) + } + +- if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { + c.Fatalf("failed to open destination dockerfile: %v", err) + } + return fakecontext.New(c, tmpDir) +@@ -2885,7 +2884,7 @@ func (s *DockerSuite) TestBuildAddBrokenTar(c *testing.T) { + dockerfile := ` + FROM busybox + ADD test.tar /` +- tmpDir, err := ioutil.TempDir("", "fake-context") ++ tmpDir, err := os.MkdirTemp("", "fake-context") + assert.NilError(c, err) + testTar, err := os.Create(filepath.Join(tmpDir, "test.tar")) + if err != nil { +@@ -2917,7 +2916,7 @@ ADD test.tar /` + c.Fatalf("failed to truncate tar archive: %v", err) + } + +- if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { + c.Fatalf("failed to open destination dockerfile: %v", err) + } + return fakecontext.New(c, tmpDir) +@@ -2953,7 +2952,7 @@ func (s *DockerSuite) TestBuildAddTarXz(c *testing.T) { + FROM busybox + ADD test.tar.xz / + RUN cat /test/foo | grep Hi` +- tmpDir, err := ioutil.TempDir("", "fake-context") ++ tmpDir, err := os.MkdirTemp("", "fake-context") + assert.NilError(c, err) + testTar, err := os.Create(filepath.Join(tmpDir, "test.tar")) + if err != nil { +@@ -2980,7 +2979,7 @@ func (s *DockerSuite) TestBuildAddTarXz(c *testing.T) { + Command: []string{"xz", "-k", "test.tar"}, + Dir: tmpDir, + }).Assert(c, icmd.Success) +- if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { + c.Fatalf("failed to open destination dockerfile: %v", err) + } + return fakecontext.New(c, tmpDir) +@@ -3000,7 +2999,7 @@ func (s *DockerSuite) TestBuildAddTarXzGz(c *testing.T) { + FROM busybox + ADD test.tar.xz.gz / + RUN ls /test.tar.xz.gz` +- tmpDir, err := ioutil.TempDir("", "fake-context") ++ tmpDir, err := os.MkdirTemp("", "fake-context") + assert.NilError(c, err) + testTar, err := os.Create(filepath.Join(tmpDir, "test.tar")) + if err != nil { +@@ -3032,7 +3031,7 @@ func (s *DockerSuite) TestBuildAddTarXzGz(c *testing.T) { + Command: []string{"gzip", "test.tar.xz"}, + Dir: tmpDir, + }) +- if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { + c.Fatalf("failed to open destination dockerfile: %v", err) + } + return fakecontext.New(c, tmpDir) +@@ -3593,7 +3592,7 @@ RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ] + + func (s *DockerSuite) TestBuildSymlinkBreakout(c *testing.T) { + name := "testbuildsymlinkbreakout" +- tmpdir, err := ioutil.TempDir("", name) ++ tmpdir, err := os.MkdirTemp("", name) + assert.NilError(c, err) + + // See https://github.com/moby/moby/pull/37770 for reason for next line. +@@ -3605,7 +3604,7 @@ func (s *DockerSuite) TestBuildSymlinkBreakout(c *testing.T) { + if err := os.MkdirAll(ctx, 0755); err != nil { + c.Fatal(err) + } +- if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(` ++ if err := os.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(` + from busybox + add symlink.tar / + add inject /symlink/ +@@ -3613,7 +3612,7 @@ func (s *DockerSuite) TestBuildSymlinkBreakout(c *testing.T) { + c.Fatal(err) + } + inject := filepath.Join(ctx, "inject") +- if err := ioutil.WriteFile(inject, nil, 0644); err != nil { ++ if err := os.WriteFile(inject, nil, 0644); err != nil { + c.Fatal(err) + } + f, err := os.Create(filepath.Join(ctx, "symlink.tar")) +@@ -3970,7 +3969,7 @@ func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) + + cgroupParent := "test" +- data, err := ioutil.ReadFile("/proc/self/cgroup") ++ data, err := os.ReadFile("/proc/self/cgroup") + if err != nil { + c.Fatalf("failed to read '/proc/self/cgroup - %v", err) + } +@@ -4768,7 +4767,7 @@ func (s *DockerSuite) TestBuildCacheBrokenSymlink(c *testing.T) { + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) + + // add new file to context, should invalidate cache +- err = ioutil.WriteFile(filepath.Join(ctx.Dir, "newfile"), []byte("foo"), 0644) ++ err = os.WriteFile(filepath.Join(ctx.Dir, "newfile"), []byte("foo"), 0644) + assert.NilError(c, err) + + result := cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) +@@ -4797,7 +4796,7 @@ func (s *DockerSuite) TestBuildFollowSymlinkToFile(c *testing.T) { + assert.Assert(c, cmp.Regexp("^bar$", out)) + + // change target file should invalidate cache +- err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644) ++ err = os.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644) + assert.NilError(c, err) + + result := cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) +@@ -4828,7 +4827,7 @@ func (s *DockerSuite) TestBuildFollowSymlinkToDir(c *testing.T) { + assert.Assert(c, cmp.Regexp("^barbaz$", out)) + + // change target file should invalidate cache +- err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo/def"), []byte("bax"), 0644) ++ err = os.WriteFile(filepath.Join(ctx.Dir, "foo/def"), []byte("bax"), 0644) + assert.NilError(c, err) + + result := cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) +@@ -4877,7 +4876,7 @@ func (s *DockerSuite) TestBuildCacheRootSource(c *testing.T) { + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) + + // change file, should invalidate cache +- err := ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644) ++ err := os.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644) + assert.NilError(c, err) + + result := cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) +@@ -5023,18 +5022,18 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestBuildWithExternalAuth(c *testing.T + + repoName := fmt.Sprintf("%v/dockercli/busybox:authtest", privateRegistryURL) + +- tmp, err := ioutil.TempDir("", "integration-cli-") ++ tmp, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + + externalAuthConfig := `{ "credsStore": "shell-test" }` + + configPath := filepath.Join(tmp, "config.json") +- err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644) ++ err = os.WriteFile(configPath, []byte(externalAuthConfig), 0644) + assert.NilError(c, err) + + dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL) + +- b, err := ioutil.ReadFile(configPath) ++ b, err := os.ReadFile(configPath) + assert.NilError(c, err) + assert.Assert(c, !strings.Contains(string(b), "\"auth\":")) + dockerCmd(c, "--config", tmp, "tag", "busybox", repoName) +@@ -5452,7 +5451,7 @@ func (s *DockerSuite) TestBuildCacheFrom(c *testing.T) { + cli.DockerCmd(c, "rmi", "build2") + + // clear parent images +- tempDir, err := ioutil.TempDir("", "test-build-cache-from-") ++ tempDir, err := os.MkdirTemp("", "test-build-cache-from-") + if err != nil { + c.Fatalf("failed to create temporary directory: %s", tempDir) + } +@@ -5490,7 +5489,7 @@ func (s *DockerSuite) TestBuildCacheFrom(c *testing.T) { + ENV FOO=bar + ADD baz / + RUN touch newfile` +- err = ioutil.WriteFile(filepath.Join(ctx.Dir, "Dockerfile"), []byte(dockerfile), 0644) ++ err = os.WriteFile(filepath.Join(ctx.Dir, "Dockerfile"), []byte(dockerfile), 0644) + assert.NilError(c, err) + + result = cli.BuildCmd(c, "build2", cli.WithFlags("--cache-from=build1"), build.WithExternalBuildContext(ctx)) +@@ -5648,14 +5647,14 @@ func (s *DockerSuite) TestBuildMultiStageCopyFromSyntax(c *testing.T) { + assert.Equal(c, strings.Count(result.Combined(), "Using cache"), 7) + assert.Equal(c, getIDByName(c, "build1"), getIDByName(c, "build2")) + +- err := ioutil.WriteFile(filepath.Join(ctx.Dir, "Dockerfile"), []byte(fmt.Sprintf(dockerfile, "COPY baz/aa foo")), 0644) ++ err := os.WriteFile(filepath.Join(ctx.Dir, "Dockerfile"), []byte(fmt.Sprintf(dockerfile, "COPY baz/aa foo")), 0644) + assert.NilError(c, err) + + // changing file in parent block should not affect last block + result = cli.BuildCmd(c, "build3", build.WithExternalBuildContext(ctx)) + assert.Equal(c, strings.Count(result.Combined(), "Using cache"), 5) + +- err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("pqr"), 0644) ++ err = os.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("pqr"), 0644) + assert.NilError(c, err) + + // changing file in parent block should affect both first and last block +@@ -6144,7 +6143,7 @@ CMD echo foo + + // FIXME(vdemeester) should migrate to docker/cli tests + func (s *DockerSuite) TestBuildIidFile(c *testing.T) { +- tmpDir, err := ioutil.TempDir("", "TestBuildIidFile") ++ tmpDir, err := os.MkdirTemp("", "TestBuildIidFile") + if err != nil { + c.Fatal(err) + } +@@ -6160,7 +6159,7 @@ FROM `+minimalBaseImage()+` + ENV BAR BAZ`), + cli.WithFlags("--iidfile", tmpIidFile)) + +- id, err := ioutil.ReadFile(tmpIidFile) ++ id, err := os.ReadFile(tmpIidFile) + assert.NilError(c, err) + d, err := digest.Parse(string(id)) + assert.NilError(c, err) +@@ -6169,14 +6168,14 @@ ENV BAR BAZ`), + + // FIXME(vdemeester) should migrate to docker/cli tests + func (s *DockerSuite) TestBuildIidFileCleanupOnFail(c *testing.T) { +- tmpDir, err := ioutil.TempDir("", "TestBuildIidFileCleanupOnFail") ++ tmpDir, err := os.MkdirTemp("", "TestBuildIidFileCleanupOnFail") + if err != nil { + c.Fatal(err) + } + defer os.RemoveAll(tmpDir) + tmpIidFile := filepath.Join(tmpDir, "iid") + +- err = ioutil.WriteFile(tmpIidFile, []byte("Dummy"), 0666) ++ err = os.WriteFile(tmpIidFile, []byte("Dummy"), 0666) + assert.NilError(c, err) + + cli.Docker(cli.Build("testbuildiidfilecleanuponfail"), +diff --git a/integration-cli/docker_cli_build_unix_test.go b/integration-cli/docker_cli_build_unix_test.go +index 31ead25bc6..92e51b611a 100644 +--- a/integration-cli/docker_cli_build_unix_test.go ++++ b/integration-cli/docker_cli_build_unix_test.go +@@ -7,7 +7,6 @@ import ( + "bufio" + "bytes" + "encoding/json" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -96,7 +95,7 @@ func (s *DockerSuite) TestBuildAddChangeOwnership(c *testing.T) { + RUN [ $(stat -c %U:%G "/bar") = 'root:root' ] + RUN [ $(stat -c %U:%G "/bar/foo") = 'root:root' ] + ` +- tmpDir, err := ioutil.TempDir("", "fake-context") ++ tmpDir, err := os.MkdirTemp("", "fake-context") + assert.NilError(c, err) + testFile, err := os.Create(filepath.Join(tmpDir, "foo")) + if err != nil { +@@ -109,7 +108,7 @@ func (s *DockerSuite) TestBuildAddChangeOwnership(c *testing.T) { + Dir: tmpDir, + }).Assert(c, icmd.Success) + +- if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { + c.Fatalf("failed to open destination dockerfile: %v", err) + } + return fakecontext.New(c, tmpDir) +diff --git a/integration-cli/docker_cli_cp_test.go b/integration-cli/docker_cli_cp_test.go +index 346c484bd5..173cf4eee5 100644 +--- a/integration-cli/docker_cli_cp_test.go ++++ b/integration-cli/docker_cli_cp_test.go +@@ -3,7 +3,7 @@ package main + import ( + "bytes" + "fmt" +- "io/ioutil" ++ "io" + "os" + "os/exec" + "path" +@@ -50,7 +50,7 @@ func (s *DockerSuite) TestCpGarbagePath(c *testing.T) { + + fmt.Fprintf(hostFile, "%s", cpHostContents) + +- tmpdir, err := ioutil.TempDir("", "docker-integration") ++ tmpdir, err := os.MkdirTemp("", "docker-integration") + assert.NilError(c, err) + + tmpname := filepath.Join(tmpdir, cpTestName) +@@ -63,7 +63,7 @@ func (s *DockerSuite) TestCpGarbagePath(c *testing.T) { + file, _ := os.Open(tmpname) + defer file.Close() + +- test, err := ioutil.ReadAll(file) ++ test, err := io.ReadAll(file) + assert.NilError(c, err) + assert.Assert(c, string(test) != cpHostContents, "output matched host file -- garbage path can escape container rootfs") + assert.Assert(c, string(test) == cpContainerContents, "output doesn't match the input for garbage path") +@@ -86,7 +86,7 @@ func (s *DockerSuite) TestCpRelativePath(c *testing.T) { + + fmt.Fprintf(hostFile, "%s", cpHostContents) + +- tmpdir, err := ioutil.TempDir("", "docker-integration") ++ tmpdir, err := os.MkdirTemp("", "docker-integration") + assert.NilError(c, err) + + tmpname := filepath.Join(tmpdir, cpTestName) +@@ -105,7 +105,7 @@ func (s *DockerSuite) TestCpRelativePath(c *testing.T) { + file, _ := os.Open(tmpname) + defer file.Close() + +- test, err := ioutil.ReadAll(file) ++ test, err := io.ReadAll(file) + assert.NilError(c, err) + assert.Assert(c, string(test) != cpHostContents, "output matched host file -- relative path can escape container rootfs") + assert.Assert(c, string(test) == cpContainerContents, "output doesn't match the input for relative path") +@@ -128,7 +128,7 @@ func (s *DockerSuite) TestCpAbsolutePath(c *testing.T) { + + fmt.Fprintf(hostFile, "%s", cpHostContents) + +- tmpdir, err := ioutil.TempDir("", "docker-integration") ++ tmpdir, err := os.MkdirTemp("", "docker-integration") + assert.NilError(c, err) + + tmpname := filepath.Join(tmpdir, cpTestName) +@@ -141,7 +141,7 @@ func (s *DockerSuite) TestCpAbsolutePath(c *testing.T) { + file, _ := os.Open(tmpname) + defer file.Close() + +- test, err := ioutil.ReadAll(file) ++ test, err := io.ReadAll(file) + assert.NilError(c, err) + assert.Assert(c, string(test) != cpHostContents, "output matched host file -- absolute path can escape container rootfs") + assert.Assert(c, string(test) == cpContainerContents, "output doesn't match the input for absolute path") +@@ -167,7 +167,7 @@ func (s *DockerSuite) TestCpAbsoluteSymlink(c *testing.T) { + + fmt.Fprintf(hostFile, "%s", cpHostContents) + +- tmpdir, err := ioutil.TempDir("", "docker-integration") ++ tmpdir, err := os.MkdirTemp("", "docker-integration") + assert.NilError(c, err) + + tmpname := filepath.Join(tmpdir, "container_path") +@@ -194,7 +194,7 @@ func (s *DockerSuite) TestCpFromSymlinkToDirectory(c *testing.T) { + out, _ = dockerCmd(c, "wait", containerID) + assert.Equal(c, strings.TrimSpace(out), "0", "failed to set up container") + +- testDir, err := ioutil.TempDir("", "test-cp-from-symlink-to-dir-") ++ testDir, err := os.MkdirTemp("", "test-cp-from-symlink-to-dir-") + assert.NilError(c, err) + defer os.RemoveAll(testDir) + +@@ -235,7 +235,7 @@ func (s *DockerSuite) TestCpToSymlinkToDirectory(c *testing.T) { + testRequires(c, DaemonIsLinux) + testRequires(c, testEnv.IsLocalDaemon) // Requires local volume mount bind. + +- testVol, err := ioutil.TempDir("", "test-cp-to-symlink-to-dir-") ++ testVol, err := os.MkdirTemp("", "test-cp-to-symlink-to-dir-") + assert.NilError(c, err) + defer os.RemoveAll(testVol) + +@@ -246,7 +246,7 @@ func (s *DockerSuite) TestCpToSymlinkToDirectory(c *testing.T) { + containerID := strings.TrimSpace(out) + + // Create a temp directory to hold a test file nested in a directory. +- testDir, err := ioutil.TempDir("", "test-cp-to-symlink-to-dir-") ++ testDir, err := os.MkdirTemp("", "test-cp-to-symlink-to-dir-") + assert.NilError(c, err) + defer os.RemoveAll(testDir) + +@@ -254,11 +254,11 @@ func (s *DockerSuite) TestCpToSymlinkToDirectory(c *testing.T) { + // the test volume later. + hostTestFilename := filepath.Join(testDir, cpFullPath) + assert.NilError(c, os.MkdirAll(filepath.Dir(hostTestFilename), os.FileMode(0700))) +- assert.NilError(c, ioutil.WriteFile(hostTestFilename, []byte(cpHostContents), os.FileMode(0600))) ++ assert.NilError(c, os.WriteFile(hostTestFilename, []byte(cpHostContents), os.FileMode(0600))) + + // Now create another temp directory to hold a symlink to the + // "/testDir/some" directory. +- linkDir, err := ioutil.TempDir("", "test-cp-to-symlink-to-dir-") ++ linkDir, err := os.MkdirTemp("", "test-cp-to-symlink-to-dir-") + assert.NilError(c, err) + defer os.RemoveAll(linkDir) + +@@ -301,7 +301,7 @@ func (s *DockerSuite) TestCpToSymlinkToDirectory(c *testing.T) { + // And this directory should contain the file copied from the host at the + // expected location: "/testVol/dir_link/path/test" + expectedFilepath := filepath.Join(testVol, "dir_link/path/test") +- fileContents, err := ioutil.ReadFile(expectedFilepath) ++ fileContents, err := os.ReadFile(expectedFilepath) + assert.NilError(c, err) + assert.Equal(c, string(fileContents), cpHostContents) + } +@@ -326,7 +326,7 @@ func (s *DockerSuite) TestCpSymlinkComponent(c *testing.T) { + + fmt.Fprintf(hostFile, "%s", cpHostContents) + +- tmpdir, err := ioutil.TempDir("", "docker-integration") ++ tmpdir, err := os.MkdirTemp("", "docker-integration") + + assert.NilError(c, err) + +@@ -340,7 +340,7 @@ func (s *DockerSuite) TestCpSymlinkComponent(c *testing.T) { + file, _ := os.Open(tmpname) + defer file.Close() + +- test, err := ioutil.ReadAll(file) ++ test, err := io.ReadAll(file) + assert.NilError(c, err) + assert.Assert(c, string(test) != cpHostContents, "output matched host file -- symlink path component can escape container rootfs") + assert.Equal(c, string(test), cpContainerContents, "output doesn't match the input for symlink path component") +@@ -358,7 +358,7 @@ func (s *DockerSuite) TestCpUnprivilegedUser(c *testing.T) { + out, _ = dockerCmd(c, "wait", containerID) + assert.Equal(c, strings.TrimSpace(out), "0", "failed to set up container") + +- tmpdir, err := ioutil.TempDir("", "docker-integration") ++ tmpdir, err := os.MkdirTemp("", "docker-integration") + assert.NilError(c, err) + + defer os.RemoveAll(tmpdir) +@@ -375,7 +375,7 @@ func (s *DockerSuite) TestCpSpecialFiles(c *testing.T) { + testRequires(c, DaemonIsLinux) + testRequires(c, testEnv.IsLocalDaemon) + +- outDir, err := ioutil.TempDir("", "cp-test-special-files") ++ outDir, err := os.MkdirTemp("", "cp-test-special-files") + assert.NilError(c, err) + defer os.RemoveAll(outDir) + +@@ -390,7 +390,7 @@ func (s *DockerSuite) TestCpSpecialFiles(c *testing.T) { + dockerCmd(c, "cp", containerID+":/etc/resolv.conf", outDir) + + expected := readContainerFile(c, containerID, "resolv.conf") +- actual, err := ioutil.ReadFile(outDir + "/resolv.conf") ++ actual, err := os.ReadFile(outDir + "/resolv.conf") + assert.NilError(c, err) + assert.Assert(c, bytes.Equal(actual, expected), "Expected copied file to be duplicate of the container resolvconf") + +@@ -398,7 +398,7 @@ func (s *DockerSuite) TestCpSpecialFiles(c *testing.T) { + dockerCmd(c, "cp", containerID+":/etc/hosts", outDir) + + expected = readContainerFile(c, containerID, "hosts") +- actual, err = ioutil.ReadFile(outDir + "/hosts") ++ actual, err = os.ReadFile(outDir + "/hosts") + assert.NilError(c, err) + assert.Assert(c, bytes.Equal(actual, expected), "Expected copied file to be duplicate of the container hosts") + +@@ -406,7 +406,7 @@ func (s *DockerSuite) TestCpSpecialFiles(c *testing.T) { + dockerCmd(c, "cp", containerID+":/etc/hostname", outDir) + + expected = readContainerFile(c, containerID, "hostname") +- actual, err = ioutil.ReadFile(outDir + "/hostname") ++ actual, err = os.ReadFile(outDir + "/hostname") + assert.NilError(c, err) + assert.Assert(c, bytes.Equal(actual, expected), "Expected copied file to be duplicate of the container hostname") + } +@@ -417,10 +417,10 @@ func (s *DockerSuite) TestCpVolumePath(c *testing.T) { + testRequires(c, DaemonIsLinux) + testRequires(c, testEnv.IsLocalDaemon) + +- tmpDir, err := ioutil.TempDir("", "cp-test-volumepath") ++ tmpDir, err := os.MkdirTemp("", "cp-test-volumepath") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir) +- outDir, err := ioutil.TempDir("", "cp-test-volumepath-out") ++ outDir, err := os.MkdirTemp("", "cp-test-volumepath-out") + assert.NilError(c, err) + defer os.RemoveAll(outDir) + _, err = os.Create(tmpDir + "/test") +@@ -459,17 +459,17 @@ func (s *DockerSuite) TestCpVolumePath(c *testing.T) { + + // Copy file nested in bind-mounted dir + dockerCmd(c, "cp", containerID+":/baz/test", outDir) +- fb, err := ioutil.ReadFile(outDir + "/baz/test") ++ fb, err := os.ReadFile(outDir + "/baz/test") + assert.NilError(c, err) +- fb2, err := ioutil.ReadFile(tmpDir + "/test") ++ fb2, err := os.ReadFile(tmpDir + "/test") + assert.NilError(c, err) + assert.Assert(c, bytes.Equal(fb, fb2), "Expected copied file to be duplicate of bind-mounted file") + + // Copy bind-mounted file + dockerCmd(c, "cp", containerID+":/test", outDir) +- fb, err = ioutil.ReadFile(outDir + "/test") ++ fb, err = os.ReadFile(outDir + "/test") + assert.NilError(c, err) +- fb2, err = ioutil.ReadFile(tmpDir + "/test") ++ fb2, err = os.ReadFile(tmpDir + "/test") + assert.NilError(c, err) + assert.Assert(c, bytes.Equal(fb, fb2), "Expected copied file to be duplicate of bind-mounted file") + } +@@ -482,7 +482,7 @@ func (s *DockerSuite) TestCpToDot(c *testing.T) { + out, _ = dockerCmd(c, "wait", containerID) + assert.Equal(c, strings.TrimSpace(out), "0", "failed to set up container") + +- tmpdir, err := ioutil.TempDir("", "docker-integration") ++ tmpdir, err := os.MkdirTemp("", "docker-integration") + assert.NilError(c, err) + defer os.RemoveAll(tmpdir) + cwd, err := os.Getwd() +@@ -492,7 +492,7 @@ func (s *DockerSuite) TestCpToDot(c *testing.T) { + assert.NilError(c, err) + + dockerCmd(c, "cp", containerID+":/test", ".") +- content, err := ioutil.ReadFile("./test") ++ content, err := os.ReadFile("./test") + assert.NilError(c, err) + assert.Equal(c, string(content), "lololol\n") + } +@@ -524,11 +524,11 @@ func (s *DockerSuite) TestCpNameHasColon(c *testing.T) { + out, _ = dockerCmd(c, "wait", containerID) + assert.Equal(c, strings.TrimSpace(out), "0", "failed to set up container") + +- tmpdir, err := ioutil.TempDir("", "docker-integration") ++ tmpdir, err := os.MkdirTemp("", "docker-integration") + assert.NilError(c, err) + defer os.RemoveAll(tmpdir) + dockerCmd(c, "cp", containerID+":/te:s:t", tmpdir) +- content, err := ioutil.ReadFile(tmpdir + "/te:s:t") ++ content, err := os.ReadFile(tmpdir + "/te:s:t") + assert.NilError(c, err) + assert.Equal(c, string(content), "lololol\n") + } +@@ -542,7 +542,7 @@ func (s *DockerSuite) TestCopyAndRestart(c *testing.T) { + out, _ = dockerCmd(c, "wait", containerID) + assert.Equal(c, strings.TrimSpace(out), "0", "failed to set up container") + +- tmpDir, err := ioutil.TempDir("", "test-docker-restart-after-copy-") ++ tmpDir, err := os.MkdirTemp("", "test-docker-restart-after-copy-") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir) + +@@ -556,7 +556,7 @@ func (s *DockerSuite) TestCopyCreatedContainer(c *testing.T) { + testRequires(c, DaemonIsLinux) + dockerCmd(c, "create", "--name", "test_cp", "-v", "/test", "busybox") + +- tmpDir, err := ioutil.TempDir("", "test") ++ tmpDir, err := os.MkdirTemp("", "test") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir) + dockerCmd(c, "cp", "test_cp:/bin/sh", tmpDir) +@@ -575,7 +575,7 @@ func (s *DockerSuite) TestCpSymlinkFromConToHostFollowSymlink(c *testing.T) { + out, _ = dockerCmd(c, "wait", cleanedContainerID) + assert.Equal(c, strings.TrimSpace(out), "0", "failed to set up container") + +- testDir, err := ioutil.TempDir("", "test-cp-symlink-container-to-host-follow-symlink") ++ testDir, err := os.MkdirTemp("", "test-cp-symlink-container-to-host-follow-symlink") + assert.NilError(c, err) + defer os.RemoveAll(testDir) + +@@ -586,7 +586,7 @@ func (s *DockerSuite) TestCpSymlinkFromConToHostFollowSymlink(c *testing.T) { + expectedPath := filepath.Join(testDir, "dir_link") + + expected := []byte(cpContainerContents) +- actual, err := ioutil.ReadFile(expectedPath) ++ actual, err := os.ReadFile(expectedPath) + assert.NilError(c, err) + os.Remove(expectedPath) + assert.Assert(c, bytes.Equal(actual, expected), "Expected copied file to be duplicate of the container symbol link target") +@@ -600,7 +600,7 @@ func (s *DockerSuite) TestCpSymlinkFromConToHostFollowSymlink(c *testing.T) { + + dockerCmd(c, "cp", "-L", cleanedContainerID+":"+"/dir_link", expectedPath) + +- actual, err = ioutil.ReadFile(expectedPath) ++ actual, err = os.ReadFile(expectedPath) + assert.NilError(c, err) + defer os.Remove(expectedPath) + assert.Assert(c, bytes.Equal(actual, expected), "Expected copied file to be duplicate of the container symbol link target") +diff --git a/integration-cli/docker_cli_cp_utils_test.go b/integration-cli/docker_cli_cp_utils_test.go +index 45af5fcafb..4ac95f5059 100644 +--- a/integration-cli/docker_cli_cp_utils_test.go ++++ b/integration-cli/docker_cli_cp_utils_test.go +@@ -3,7 +3,7 @@ package main + import ( + "bytes" + "fmt" +- "io/ioutil" ++ "io" + "os" + "os/exec" + "path/filepath" +@@ -98,7 +98,7 @@ func makeTestContentInDir(c *testing.T, dir string) { + path := filepath.Join(dir, filepath.FromSlash(fd.path)) + switch fd.filetype { + case ftRegular: +- assert.NilError(c, ioutil.WriteFile(path, []byte(fd.contents+"\n"), os.FileMode(fd.mode))) ++ assert.NilError(c, os.WriteFile(path, []byte(fd.contents+"\n"), os.FileMode(fd.mode))) + case ftDir: + assert.NilError(c, os.Mkdir(path, os.FileMode(fd.mode))) + case ftSymlink: +@@ -217,7 +217,7 @@ func getTestDir(c *testing.T, label string) (tmpDir string) { + c.Helper() + var err error + +- tmpDir, err = ioutil.TempDir("", label) ++ tmpDir, err = os.MkdirTemp("", label) + // unable to make temporary directory + assert.NilError(c, err) + +@@ -239,12 +239,12 @@ func isCpCannotCopyReadOnly(err error) bool { + func fileContentEquals(c *testing.T, filename, contents string) error { + c.Helper() + +- fileBytes, err := ioutil.ReadFile(filename) ++ fileBytes, err := os.ReadFile(filename) + if err != nil { + return err + } + +- expectedBytes, err := ioutil.ReadAll(strings.NewReader(contents)) ++ expectedBytes, err := io.ReadAll(strings.NewReader(contents)) + if err != nil { + return err + } +diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go +index 4b750027dd..443f12e96e 100644 +--- a/integration-cli/docker_cli_daemon_test.go ++++ b/integration-cli/docker_cli_daemon_test.go +@@ -12,7 +12,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net" + "os" + "os/exec" +@@ -1165,7 +1164,7 @@ func (s *DockerDaemonSuite) TestDaemonLoggingDriverShouldBeIgnoredForBuild(c *te + } + + func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *testing.T) { +- dir, err := ioutil.TempDir("", "socket-cleanup-test") ++ dir, err := os.MkdirTemp("", "socket-cleanup-test") + if err != nil { + c.Fatal(err) + } +@@ -1200,7 +1199,7 @@ func (s *DockerDaemonSuite) TestDaemonWithWrongkey(c *testing.T) { + s.d.Stop(c) + + config := &Config{} +- bytes, err := ioutil.ReadFile("/etc/docker/key.json") ++ bytes, err := os.ReadFile("/etc/docker/key.json") + if err != nil { + c.Fatalf("Error reading key.json file: %s", err) + } +@@ -1220,8 +1219,8 @@ func (s *DockerDaemonSuite) TestDaemonWithWrongkey(c *testing.T) { + } + + // write back +- if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil { +- c.Fatalf("Error ioutil.WriteFile: %s", err) ++ if err := os.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil { ++ c.Fatalf("Error os.WriteFile: %s", err) + } + + defer os.Remove("/etc/docker/key.json") +@@ -1438,7 +1437,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *test + // If there are no mounts with container id visible from the host + // (as those are in container's own mount ns), there is nothing + // to check here and the test should be skipped. +- mountOut, err := ioutil.ReadFile("/proc/self/mountinfo") ++ mountOut, err := os.ReadFile("/proc/self/mountinfo") + assert.NilError(c, err, "Output: %s", mountOut) + if !strings.Contains(string(mountOut), id) { + d.Stop(c) +@@ -1456,7 +1455,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *test + d.Restart(c) + + // Now, container mounts should be gone. +- mountOut, err = ioutil.ReadFile("/proc/self/mountinfo") ++ mountOut, err = os.ReadFile("/proc/self/mountinfo") + assert.NilError(c, err, "Output: %s", mountOut) + assert.Assert(c, !strings.Contains(string(mountOut), id), "%s is still mounted from older daemon start:\nDaemon root repository %s\n%s", id, d.Root, mountOut) + +@@ -1477,7 +1476,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterGracefulShutdown(c *testing.T) + // Wait for the daemon to stop. + assert.NilError(c, <-d.Wait) + +- mountOut, err := ioutil.ReadFile("/proc/self/mountinfo") ++ mountOut, err := os.ReadFile("/proc/self/mountinfo") + assert.NilError(c, err, "Output: %s", mountOut) + + assert.Assert(c, !strings.Contains(string(mountOut), id), "%s is still mounted from older daemon start:\nDaemon root repository %s\n%s", id, d.Root, mountOut) +@@ -1713,7 +1712,7 @@ func (s *DockerDaemonSuite) TestDaemonStartWithDefaultTLSHost(c *testing.T) { + } + + // ensure when connecting to the server that only a single acceptable CA is requested +- contents, err := ioutil.ReadFile("fixtures/https/ca.pem") ++ contents, err := os.ReadFile("fixtures/https/ca.pem") + assert.NilError(c, err) + rootCert, err := helpers.ParseCertificatePEM(contents) + assert.NilError(c, err) +@@ -1770,7 +1769,7 @@ func (s *DockerDaemonSuite) TestBridgeIPIsExcludedFromAllocatorPool(c *testing.T + func (s *DockerDaemonSuite) TestDaemonNoSpaceLeftOnDeviceError(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux, Network) + +- testDir, err := ioutil.TempDir("", "no-space-left-on-device-test") ++ testDir, err := os.MkdirTemp("", "no-space-left-on-device-test") + assert.NilError(c, err) + defer os.RemoveAll(testDir) + assert.Assert(c, mount.MakeRShared(testDir) == nil) +@@ -1846,7 +1845,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartContainerLinksRestart(c *testing.T) + out, err := s.d.Cmd("inspect", "-f", "{{ .State.Running }}", "parent"+num) + assert.NilError(c, err) + if strings.TrimSpace(out) != "true" { +- log, _ := ioutil.ReadFile(s.d.LogFileName()) ++ log, _ := os.ReadFile(s.d.LogFileName()) + c.Fatalf("parent container is not running\n%s", string(log)) + } + } +@@ -2015,7 +2014,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonCrash(c *testing.T) { + // If not, those mounts exist in container's own mount ns, and so + // the following check for mounts being cleared is pointless. + skipMountCheck := false +- mountOut, err := ioutil.ReadFile("/proc/self/mountinfo") ++ mountOut, err := os.ReadFile("/proc/self/mountinfo") + assert.Assert(c, err == nil, "Output: %s", mountOut) + if !strings.Contains(string(mountOut), id) { + skipMountCheck = true +@@ -2040,7 +2039,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonCrash(c *testing.T) { + return + } + // Now, container mounts should be gone. +- mountOut, err = ioutil.ReadFile("/proc/self/mountinfo") ++ mountOut, err = os.ReadFile("/proc/self/mountinfo") + assert.Assert(c, err == nil, "Output: %s", mountOut) + comment := fmt.Sprintf("%s is still mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.Root, mountOut) + assert.Equal(c, strings.Contains(string(mountOut), id), false, comment) +@@ -2202,7 +2201,7 @@ func (s *DockerDaemonSuite) TestDaemonDiscoveryBackendConfigReload(c *testing.T) + + // daemon config file + daemonConfig := `{ "debug" : false }` +- configFile, err := ioutil.TempFile("", "test-daemon-discovery-backend-config-reload-config") ++ configFile, err := os.CreateTemp("", "test-daemon-discovery-backend-config-reload-config") + assert.Assert(c, err == nil, "could not create temp file for config reload") + configFilePath := configFile.Name() + defer func() { +@@ -2393,7 +2392,7 @@ func (s *DockerDaemonSuite) TestDaemonDNSFlagsInHostMode(c *testing.T) { + } + + func (s *DockerDaemonSuite) TestRunWithRuntimeFromConfigFile(c *testing.T) { +- conf, err := ioutil.TempFile("", "config-file-") ++ conf, err := os.CreateTemp("", "config-file-") + assert.NilError(c, err) + configName := conf.Name() + conf.Close() +@@ -2414,7 +2413,7 @@ func (s *DockerDaemonSuite) TestRunWithRuntimeFromConfigFile(c *testing.T) { + } + } + ` +- ioutil.WriteFile(configName, []byte(config), 0644) ++ os.WriteFile(configName, []byte(config), 0644) + s.d.StartWithBusybox(c, "--config-file", configName) + + // Run with default runtime +@@ -2440,7 +2439,7 @@ func (s *DockerDaemonSuite) TestRunWithRuntimeFromConfigFile(c *testing.T) { + } + } + ` +- ioutil.WriteFile(configName, []byte(config), 0644) ++ os.WriteFile(configName, []byte(config), 0644) + assert.Assert(c, s.d.Signal(unix.SIGHUP) == nil) + // Give daemon time to reload config + <-time.After(1 * time.Second) +@@ -2467,7 +2466,7 @@ func (s *DockerDaemonSuite) TestRunWithRuntimeFromConfigFile(c *testing.T) { + } + } + ` +- ioutil.WriteFile(configName, []byte(config), 0644) ++ os.WriteFile(configName, []byte(config), 0644) + assert.Assert(c, s.d.Signal(unix.SIGHUP) == nil) + // Give daemon time to reload config + <-time.After(1 * time.Second) +@@ -2492,7 +2491,7 @@ func (s *DockerDaemonSuite) TestRunWithRuntimeFromConfigFile(c *testing.T) { + } + } + ` +- ioutil.WriteFile(configName, []byte(config), 0644) ++ os.WriteFile(configName, []byte(config), 0644) + assert.Assert(c, s.d.Signal(unix.SIGHUP) == nil) + // Give daemon time to reload config + <-time.After(1 * time.Second) +@@ -2627,7 +2626,7 @@ func (s *DockerDaemonSuite) TestDaemonWithUserlandProxyPath(c *testing.T) { + + dockerProxyPath, err := exec.LookPath("docker-proxy") + assert.NilError(c, err) +- tmpDir, err := ioutil.TempDir("", "test-docker-proxy") ++ tmpDir, err := os.MkdirTemp("", "test-docker-proxy") + assert.NilError(c, err) + + newProxyPath := filepath.Join(tmpDir, "docker-proxy") +@@ -2846,14 +2845,14 @@ func (s *DockerDaemonSuite) TestShmSize(c *testing.T) { + func (s *DockerDaemonSuite) TestShmSizeReload(c *testing.T) { + testRequires(c, DaemonIsLinux) + +- configPath, err := ioutil.TempDir("", "test-daemon-shm-size-reload-config") ++ configPath, err := os.MkdirTemp("", "test-daemon-shm-size-reload-config") + assert.Assert(c, err == nil, "could not create temp file for config reload") + defer os.RemoveAll(configPath) // clean up + configFile := filepath.Join(configPath, "config.json") + + size := 67108864 * 2 + configData := []byte(fmt.Sprintf(`{"default-shm-size": "%dM"}`, size/1024/1024)) +- assert.Assert(c, ioutil.WriteFile(configFile, configData, 0666) == nil, "could not write temp file for config reload") ++ assert.Assert(c, os.WriteFile(configFile, configData, 0666) == nil, "could not write temp file for config reload") + pattern := regexp.MustCompile(fmt.Sprintf("shm on /dev/shm type tmpfs(.*)size=%dk", size/1024)) + + s.d.StartWithBusybox(c, "--config-file", configFile) +@@ -2868,7 +2867,7 @@ func (s *DockerDaemonSuite) TestShmSizeReload(c *testing.T) { + + size = 67108864 * 3 + configData = []byte(fmt.Sprintf(`{"default-shm-size": "%dM"}`, size/1024/1024)) +- assert.Assert(c, ioutil.WriteFile(configFile, configData, 0666) == nil, "could not write temp file for config reload") ++ assert.Assert(c, os.WriteFile(configFile, configData, 0666) == nil, "could not write temp file for config reload") + pattern = regexp.MustCompile(fmt.Sprintf("shm on /dev/shm type tmpfs(.*)size=%dk", size/1024)) + + err = s.d.ReloadConfig() +@@ -2889,7 +2888,7 @@ func testDaemonStartIpcMode(c *testing.T, from, mode string, valid bool) { + var serr error + switch from { + case "config": +- f, err := ioutil.TempFile("", "test-daemon-ipc-config") ++ f, err := os.CreateTemp("", "test-daemon-ipc-config") + assert.NilError(c, err) + defer os.Remove(f.Name()) + config := `{"default-ipc-mode": "` + mode + `"}` +@@ -2959,7 +2958,7 @@ func (s *DockerDaemonSuite) TestFailedPluginRemove(c *testing.T) { + }) + assert.NilError(c, err) + defer out.Close() +- io.Copy(ioutil.Discard, out) ++ io.Copy(io.Discard, out) + + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() +diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go +index 629ca49a85..8069c18bd0 100644 +--- a/integration-cli/docker_cli_events_test.go ++++ b/integration-cli/docker_cli_events_test.go +@@ -6,7 +6,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "os" + "os/exec" + "strconv" +@@ -418,7 +417,7 @@ func (s *DockerSuite) TestEventsCopy(c *testing.T) { + id := getIDByName(c, "cpimg") + + // Create an empty test file. +- tempFile, err := ioutil.TempFile("", "test-events-copy-") ++ tempFile, err := os.CreateTemp("", "test-events-copy-") + assert.NilError(c, err) + defer os.Remove(tempFile.Name()) + +diff --git a/integration-cli/docker_cli_events_unix_test.go b/integration-cli/docker_cli_events_unix_test.go +index 3bb7b6539f..b60bde4af4 100644 +--- a/integration-cli/docker_cli_events_unix_test.go ++++ b/integration-cli/docker_cli_events_unix_test.go +@@ -7,7 +7,6 @@ import ( + "bufio" + "bytes" + "fmt" +- "io/ioutil" + "os" + "os/exec" + "strings" +@@ -27,7 +26,7 @@ func (s *DockerSuite) TestEventsRedirectStdout(c *testing.T) { + since := daemonUnixTime(c) + dockerCmd(c, "run", "busybox", "true") + +- file, err := ioutil.TempFile("", "") ++ file, err := os.CreateTemp("", "") + assert.NilError(c, err, "could not create temp file") + defer os.Remove(file.Name()) + +@@ -396,14 +395,14 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *testing.T) { + defer os.Remove(configFilePath) + + daemonConfig := `{"labels":["foo=bar"]}` +- err := ioutil.WriteFile(configFilePath, []byte(daemonConfig), 0644) ++ err := os.WriteFile(configFilePath, []byte(daemonConfig), 0644) + assert.NilError(c, err) + s.d.Start(c, "--config-file="+configFilePath) + + info := s.d.Info(c) + + daemonConfig = `{"max-concurrent-downloads":1,"labels":["bar=foo"], "shutdown-timeout": 10}` +- err = ioutil.WriteFile(configFilePath, []byte(daemonConfig), 0644) ++ err = os.WriteFile(configFilePath, []byte(daemonConfig), 0644) + assert.NilError(c, err) + + assert.NilError(c, s.d.Signal(unix.SIGHUP)) +@@ -447,7 +446,7 @@ func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *testing.T) { + defer os.Remove(configFilePath) + + daemonConfig := `{"labels":["foo=bar"]}` +- err := ioutil.WriteFile(configFilePath, []byte(daemonConfig), 0644) ++ err := os.WriteFile(configFilePath, []byte(daemonConfig), 0644) + assert.NilError(c, err) + s.d.Start(c, "--config-file="+configFilePath) + +diff --git a/integration-cli/docker_cli_external_volume_driver_test.go b/integration-cli/docker_cli_external_volume_driver_test.go +index 957040c17f..0428b7cc20 100644 +--- a/integration-cli/docker_cli_external_volume_driver_test.go ++++ b/integration-cli/docker_cli_external_volume_driver_test.go +@@ -4,7 +4,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net/http" + "net/http/httptest" + "os" +@@ -221,12 +220,12 @@ func newVolumePlugin(c *testing.T, name string) *volumePlugin { + return + } + +- if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte(s.Server.URL), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(p, "test"), []byte(s.Server.URL), 0644); err != nil { + send(w, err) + return + } + +- if err := ioutil.WriteFile(filepath.Join(p, "mountID"), []byte(pr.ID), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(p, "mountID"), []byte(pr.ID), 0644); err != nil { + send(w, err) + return + } +@@ -261,7 +260,7 @@ func newVolumePlugin(c *testing.T, name string) *volumePlugin { + err := os.MkdirAll("/etc/docker/plugins", 0755) + assert.NilError(c, err) + +- err = ioutil.WriteFile("/etc/docker/plugins/"+name+".spec", []byte(s.Server.URL), 0644) ++ err = os.WriteFile("/etc/docker/plugins/"+name+".spec", []byte(s.Server.URL), 0644) + assert.NilError(c, err) + return s + } +@@ -360,7 +359,7 @@ func hostVolumePath(name string) string { + // Make sure a request to use a down driver doesn't block other requests + func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverLookupNotBlocked(c *testing.T) { + specPath := "/etc/docker/plugins/down-driver.spec" +- err := ioutil.WriteFile(specPath, []byte("tcp://127.0.0.7:9999"), 0644) ++ err := os.WriteFile(specPath, []byte("tcp://127.0.0.7:9999"), 0644) + assert.NilError(c, err) + defer os.RemoveAll(specPath) + +diff --git a/integration-cli/docker_cli_images_test.go b/integration-cli/docker_cli_images_test.go +index 48b9601a0b..193cb20ab0 100644 +--- a/integration-cli/docker_cli_images_test.go ++++ b/integration-cli/docker_cli_images_test.go +@@ -2,7 +2,6 @@ package main + + import ( + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "reflect" +@@ -352,11 +351,11 @@ func (s *DockerSuite) TestImagesFormatDefaultFormat(c *testing.T) { + config := `{ + "imagesFormat": "{{ .ID }} default" + }` +- d, err := ioutil.TempDir("", "integration-cli-") ++ d, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + defer os.RemoveAll(d) + +- err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) ++ err = os.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) + assert.NilError(c, err) + + out, _ = dockerCmd(c, "--config", d, "images", "-q", "myimage") +diff --git a/integration-cli/docker_cli_import_test.go b/integration-cli/docker_cli_import_test.go +index 9114a689cc..03ce0b9fac 100644 +--- a/integration-cli/docker_cli_import_test.go ++++ b/integration-cli/docker_cli_import_test.go +@@ -3,7 +3,6 @@ package main + import ( + "bufio" + "compress/gzip" +- "io/ioutil" + "os" + "os/exec" + "regexp" +@@ -48,7 +47,7 @@ func (s *DockerSuite) TestImportFile(c *testing.T) { + testRequires(c, DaemonIsLinux) + dockerCmd(c, "run", "--name", "test-import", "busybox", "true") + +- temporaryFile, err := ioutil.TempFile("", "exportImportTest") ++ temporaryFile, err := os.CreateTemp("", "exportImportTest") + assert.Assert(c, err == nil, "failed to create temporary file") + defer os.Remove(temporaryFile.Name()) + +@@ -69,7 +68,7 @@ func (s *DockerSuite) TestImportGzipped(c *testing.T) { + testRequires(c, DaemonIsLinux) + dockerCmd(c, "run", "--name", "test-import", "busybox", "true") + +- temporaryFile, err := ioutil.TempFile("", "exportImportTest") ++ temporaryFile, err := os.CreateTemp("", "exportImportTest") + assert.Assert(c, err == nil, "failed to create temporary file") + defer os.Remove(temporaryFile.Name()) + +@@ -92,7 +91,7 @@ func (s *DockerSuite) TestImportFileWithMessage(c *testing.T) { + testRequires(c, DaemonIsLinux) + dockerCmd(c, "run", "--name", "test-import", "busybox", "true") + +- temporaryFile, err := ioutil.TempFile("", "exportImportTest") ++ temporaryFile, err := os.CreateTemp("", "exportImportTest") + assert.Assert(c, err == nil, "failed to create temporary file") + defer os.Remove(temporaryFile.Name()) + +@@ -128,7 +127,7 @@ func (s *DockerSuite) TestImportWithQuotedChanges(c *testing.T) { + testRequires(c, DaemonIsLinux) + cli.DockerCmd(c, "run", "--name", "test-import", "busybox", "true") + +- temporaryFile, err := ioutil.TempFile("", "exportImportTest") ++ temporaryFile, err := os.CreateTemp("", "exportImportTest") + assert.Assert(c, err == nil, "failed to create temporary file") + defer os.Remove(temporaryFile.Name()) + +diff --git a/integration-cli/docker_cli_logout_test.go b/integration-cli/docker_cli_logout_test.go +index c146ccf8a9..37d5a2742e 100644 +--- a/integration-cli/docker_cli_logout_test.go ++++ b/integration-cli/docker_cli_logout_test.go +@@ -3,7 +3,6 @@ package main + import ( + "bytes" + "fmt" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -29,20 +28,20 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *testing. + + repoName := fmt.Sprintf("%v/dockercli/busybox:authtest", privateRegistryURL) + +- tmp, err := ioutil.TempDir("", "integration-cli-") ++ tmp, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + defer os.RemoveAll(tmp) + + externalAuthConfig := `{ "credsStore": "shell-test" }` + + configPath := filepath.Join(tmp, "config.json") +- err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644) ++ err = os.WriteFile(configPath, []byte(externalAuthConfig), 0644) + assert.NilError(c, err) + + _, err = s.d.Cmd("--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL) + assert.NilError(c, err) + +- b, err := ioutil.ReadFile(configPath) ++ b, err := os.ReadFile(configPath) + assert.NilError(c, err) + assert.Assert(c, !strings.Contains(string(b), `"auth":`)) + assert.Assert(c, strings.Contains(string(b), privateRegistryURL)) +@@ -54,7 +53,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *testing. + _, err = s.d.Cmd("--config", tmp, "logout", privateRegistryURL) + assert.NilError(c, err) + +- b, err = ioutil.ReadFile(configPath) ++ b, err = os.ReadFile(configPath) + assert.NilError(c, err) + assert.Assert(c, !strings.Contains(string(b), privateRegistryURL)) + +@@ -82,25 +81,25 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithWrongHostnamesStored(c * + cmd.Stdin = stdin + assert.NilError(c, cmd.Run()) + +- tmp, err := ioutil.TempDir("", "integration-cli-") ++ tmp, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + + externalAuthConfig := fmt.Sprintf(`{ "auths": {"https://%s": {}}, "credsStore": "shell-test" }`, privateRegistryURL) + + configPath := filepath.Join(tmp, "config.json") +- err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644) ++ err = os.WriteFile(configPath, []byte(externalAuthConfig), 0644) + assert.NilError(c, err) + + dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL) + +- b, err := ioutil.ReadFile(configPath) ++ b, err := os.ReadFile(configPath) + assert.NilError(c, err) + assert.Assert(c, strings.Contains(string(b), fmt.Sprintf(`"https://%s": {}`, privateRegistryURL))) + assert.Assert(c, strings.Contains(string(b), fmt.Sprintf(`"%s": {}`, privateRegistryURL))) + + dockerCmd(c, "--config", tmp, "logout", privateRegistryURL) + +- b, err = ioutil.ReadFile(configPath) ++ b, err = os.ReadFile(configPath) + assert.NilError(c, err) + assert.Assert(c, !strings.Contains(string(b), fmt.Sprintf(`"https://%s": {}`, privateRegistryURL))) + assert.Assert(c, !strings.Contains(string(b), fmt.Sprintf(`"%s": {}`, privateRegistryURL))) +diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go +index f3906f9dc8..3b14a5ee1b 100644 +--- a/integration-cli/docker_cli_network_unix_test.go ++++ b/integration-cli/docker_cli_network_unix_test.go +@@ -6,7 +6,6 @@ package main + import ( + "encoding/json" + "fmt" +- "io/ioutil" + "net" + "net/http" + "net/http/httptest" +@@ -201,11 +200,11 @@ func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ip + assert.NilError(c, err) + + fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv) +- err = ioutil.WriteFile(fileName, []byte(url), 0644) ++ err = os.WriteFile(fileName, []byte(url), 0644) + assert.NilError(c, err) + + ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv) +- err = ioutil.WriteFile(ipamFileName, []byte(url), 0644) ++ err = os.WriteFile(ipamFileName, []byte(url), 0644) + assert.NilError(c, err) + } + +diff --git a/integration-cli/docker_cli_plugins_test.go b/integration-cli/docker_cli_plugins_test.go +index 71e7eabe07..7161867669 100644 +--- a/integration-cli/docker_cli_plugins_test.go ++++ b/integration-cli/docker_cli_plugins_test.go +@@ -3,7 +3,7 @@ package main + import ( + "context" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "os" + "path" +@@ -241,12 +241,12 @@ func (ps *DockerPluginSuite) TestPluginEnableDisableNegative(c *testing.T) { + + func (ps *DockerPluginSuite) TestPluginCreate(c *testing.T) { + name := "foo/bar-driver" +- temp, err := ioutil.TempDir("", "foo") ++ temp, err := os.MkdirTemp("", "foo") + assert.NilError(c, err) + defer os.RemoveAll(temp) + + data := `{"description": "foo plugin"}` +- err = ioutil.WriteFile(filepath.Join(temp, "config.json"), []byte(data), 0644) ++ err = os.WriteFile(filepath.Join(temp, "config.json"), []byte(data), 0644) + assert.NilError(c, err) + + err = os.MkdirAll(filepath.Join(temp, "rootfs"), 0700) +@@ -381,11 +381,11 @@ func (ps *DockerPluginSuite) TestPluginIDPrefix(c *testing.T) { + } + + func (ps *DockerPluginSuite) TestPluginListDefaultFormat(c *testing.T) { +- config, err := ioutil.TempDir("", "config-file-") ++ config, err := os.MkdirTemp("", "config-file-") + assert.NilError(c, err) + defer os.RemoveAll(config) + +- err = ioutil.WriteFile(filepath.Join(config, "config.json"), []byte(`{"pluginsFormat": "raw"}`), 0644) ++ err = os.WriteFile(filepath.Join(config, "config.json"), []byte(`{"pluginsFormat": "raw"}`), 0644) + assert.NilError(c, err) + + name := "test:latest" +@@ -457,7 +457,7 @@ func (s *DockerSuite) TestPluginMetricsCollector(c *testing.T) { + assert.NilError(c, err) + defer resp.Body.Close() + +- b, err := ioutil.ReadAll(resp.Body) ++ b, err := io.ReadAll(resp.Body) + assert.NilError(c, err) + // check that a known metric is there... don't expect this metric to change over time.. probably safe + assert.Assert(c, strings.Contains(string(b), "container_actions")) +diff --git a/integration-cli/docker_cli_prune_unix_test.go b/integration-cli/docker_cli_prune_unix_test.go +index c663938b47..f3afe70a20 100644 +--- a/integration-cli/docker_cli_prune_unix_test.go ++++ b/integration-cli/docker_cli_prune_unix_test.go +@@ -4,7 +4,6 @@ + package main + + import ( +- "io/ioutil" + "os" + "path/filepath" + "strconv" +@@ -148,10 +147,10 @@ func (s *DockerSuite) TestPruneContainerLabel(c *testing.T) { + + // Add a config file of label=foobar, that will have no impact if cli is label!=foobar + config := `{"pruneFilters": ["label=foobar"]}` +- d, err := ioutil.TempDir("", "integration-cli-") ++ d, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + defer os.RemoveAll(d) +- err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) ++ err = os.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) + assert.NilError(c, err) + + // With config.json only, prune based on label=foobar +@@ -200,10 +199,10 @@ func (s *DockerSuite) TestPruneVolumeLabel(c *testing.T) { + + // Add a config file of label=foobar, that will have no impact if cli is label!=foobar + config := `{"pruneFilters": ["label=foobar"]}` +- d, err := ioutil.TempDir("", "integration-cli-") ++ d, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + defer os.RemoveAll(d) +- err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) ++ err = os.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) + assert.NilError(c, err) + + // With config.json only, prune based on label=foobar +diff --git a/integration-cli/docker_cli_pull_local_test.go b/integration-cli/docker_cli_pull_local_test.go +index 4a3cf6215b..489ca504fe 100644 +--- a/integration-cli/docker_cli_pull_local_test.go ++++ b/integration-cli/docker_cli_pull_local_test.go +@@ -3,7 +3,6 @@ package main + import ( + "encoding/json" + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -333,7 +332,7 @@ func (s *DockerRegistrySuite) TestPullManifestList(c *testing.T) { + err = os.MkdirAll(blobDir, 0755) + assert.NilError(c, err, "error creating blob dir") + blobPath := filepath.Join(blobDir, "data") +- err = ioutil.WriteFile(blobPath, manifestListJSON, 0644) ++ err = os.WriteFile(blobPath, manifestListJSON, 0644) + assert.NilError(c, err, "error writing manifest list") + + // Add to revision store +@@ -341,12 +340,12 @@ func (s *DockerRegistrySuite) TestPullManifestList(c *testing.T) { + err = os.Mkdir(revisionDir, 0755) + assert.Assert(c, err == nil, "error creating revision dir") + revisionPath := filepath.Join(revisionDir, "link") +- err = ioutil.WriteFile(revisionPath, []byte(manifestListDigest.String()), 0644) ++ err = os.WriteFile(revisionPath, []byte(manifestListDigest.String()), 0644) + assert.Assert(c, err == nil, "error writing revision link") + + // Update tag + tagPath := filepath.Join(registryV2Path, "repositories", remoteRepoName, "_manifests", "tags", "latest", "current", "link") +- err = ioutil.WriteFile(tagPath, []byte(manifestListDigest.String()), 0644) ++ err = os.WriteFile(tagPath, []byte(manifestListDigest.String()), 0644) + assert.NilError(c, err, "error writing tag link") + + // Verify that the image can be pulled through the manifest list. +@@ -381,18 +380,18 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullWithExternalAuthLoginWithSchem + + repoName := fmt.Sprintf("%v/dockercli/busybox:authtest", privateRegistryURL) + +- tmp, err := ioutil.TempDir("", "integration-cli-") ++ tmp, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + + externalAuthConfig := `{ "credsStore": "shell-test" }` + + configPath := filepath.Join(tmp, "config.json") +- err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644) ++ err = os.WriteFile(configPath, []byte(externalAuthConfig), 0644) + assert.NilError(c, err) + + dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL) + +- b, err := ioutil.ReadFile(configPath) ++ b, err := os.ReadFile(configPath) + assert.NilError(c, err) + assert.Assert(c, !strings.Contains(string(b), "\"auth\":")) + dockerCmd(c, "--config", tmp, "tag", "busybox", repoName) +@@ -425,18 +424,18 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullWithExternalAuth(c *testing.T) + + repoName := fmt.Sprintf("%v/dockercli/busybox:authtest", privateRegistryURL) + +- tmp, err := ioutil.TempDir("", "integration-cli-") ++ tmp, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + + externalAuthConfig := `{ "credsStore": "shell-test" }` + + configPath := filepath.Join(tmp, "config.json") +- err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644) ++ err = os.WriteFile(configPath, []byte(externalAuthConfig), 0644) + assert.NilError(c, err) + + dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL) + +- b, err := ioutil.ReadFile(configPath) ++ b, err := os.ReadFile(configPath) + assert.NilError(c, err) + assert.Assert(c, !strings.Contains(string(b), "\"auth\":")) + dockerCmd(c, "--config", tmp, "tag", "busybox", repoName) +diff --git a/integration-cli/docker_cli_push_test.go b/integration-cli/docker_cli_push_test.go +index 886b1780d9..b7e2c37179 100644 +--- a/integration-cli/docker_cli_push_test.go ++++ b/integration-cli/docker_cli_push_test.go +@@ -3,7 +3,6 @@ package main + import ( + "archive/tar" + "fmt" +- "io/ioutil" + "net/http" + "net/http/httptest" + "os" +@@ -123,7 +122,7 @@ func (s *DockerSchema1RegistrySuite) TestPushMultipleTags(c *testing.T) { + + func testPushEmptyLayer(c *testing.T) { + repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL) +- emptyTarball, err := ioutil.TempFile("", "empty_tarball") ++ emptyTarball, err := os.CreateTemp("", "empty_tarball") + assert.NilError(c, err, "Unable to create test file") + + tw := tar.NewWriter(emptyTarball) +diff --git a/integration-cli/docker_cli_registry_user_agent_test.go b/integration-cli/docker_cli_registry_user_agent_test.go +index baf94a2e48..13e2c8058e 100644 +--- a/integration-cli/docker_cli_registry_user_agent_test.go ++++ b/integration-cli/docker_cli_registry_user_agent_test.go +@@ -2,7 +2,6 @@ package main + + import ( + "fmt" +- "io/ioutil" + "net/http" + "os" + "regexp" +@@ -83,7 +82,7 @@ func (s *DockerRegistrySuite) TestUserAgentPassThrough(c *testing.T) { + + s.d.StartWithBusybox(c, "--insecure-registry", reg.URL()) + +- tmp, err := ioutil.TempDir("", "integration-cli-") ++ tmp, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + defer os.RemoveAll(tmp) + +diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go +index 6a8e29a365..6675b0599d 100644 +--- a/integration-cli/docker_cli_run_test.go ++++ b/integration-cli/docker_cli_run_test.go +@@ -7,7 +7,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net" + "os" + "os/exec" +@@ -384,7 +383,7 @@ func (s *DockerSuite) TestRunCreateVolumesInSymlinkDir(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) + name := "test-volume-symlink" + +- dir, err := ioutil.TempDir("", name) ++ dir, err := os.MkdirTemp("", name) + if err != nil { + c.Fatal(err) + } +@@ -620,7 +619,7 @@ func (s *DockerSuite) TestRunCreateVolume(c *testing.T) { + func (s *DockerSuite) TestRunCreateVolumeWithSymlink(c *testing.T) { + // Cannot run on Windows as relies on Linux-specific functionality (sh -c mount...) + testRequires(c, DaemonIsLinux) +- workingDirectory, err := ioutil.TempDir("", "TestRunCreateVolumeWithSymlink") ++ workingDirectory, err := os.MkdirTemp("", "TestRunCreateVolumeWithSymlink") + assert.NilError(c, err) + image := "docker-test-createvolumewithsymlink" + +@@ -658,7 +657,7 @@ func (s *DockerSuite) TestRunVolumesFromSymlinkPath(c *testing.T) { + // Windows does not support symlinks inside a volume path + testRequires(c, DaemonIsLinux) + +- workingDirectory, err := ioutil.TempDir("", "TestRunVolumesFromSymlinkPath") ++ workingDirectory, err := os.MkdirTemp("", "TestRunVolumesFromSymlinkPath") + assert.NilError(c, err) + name := "docker-test-volumesfromsymlinkpath" + prefix := "" +@@ -1254,13 +1253,13 @@ func (s *DockerSuite) TestRunDNSDefaultOptions(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) + + // preserve original resolv.conf for restoring after test +- origResolvConf, err := ioutil.ReadFile("/etc/resolv.conf") ++ origResolvConf, err := os.ReadFile("/etc/resolv.conf") + if os.IsNotExist(err) { + c.Fatalf("/etc/resolv.conf does not exist") + } + // defer restored original conf + defer func() { +- if err := ioutil.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil { + c.Fatal(err) + } + }() +@@ -1269,7 +1268,7 @@ func (s *DockerSuite) TestRunDNSDefaultOptions(c *testing.T) { + // 2 are removed from the file at container start, and the 3rd (commented out) one is ignored by + // GetNameservers(), leading to a replacement of nameservers with the default set + tmpResolvConf := []byte("nameserver 127.0.0.1\n#nameserver 127.0.2.1\nnameserver ::1") +- if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { + c.Fatal(err) + } + +@@ -1321,7 +1320,7 @@ func (s *DockerSuite) TestRunDNSOptionsBasedOnHostResolvConf(c *testing.T) { + // Not applicable on Windows as testing Unix specific functionality + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) + +- origResolvConf, err := ioutil.ReadFile("/etc/resolv.conf") ++ origResolvConf, err := os.ReadFile("/etc/resolv.conf") + if os.IsNotExist(err) { + c.Fatalf("/etc/resolv.conf does not exist") + } +@@ -1364,17 +1363,17 @@ func (s *DockerSuite) TestRunDNSOptionsBasedOnHostResolvConf(c *testing.T) { + + // test with file + tmpResolvConf := []byte("search example.com\nnameserver 12.34.56.78\nnameserver 127.0.0.1") +- if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { + c.Fatal(err) + } + // put the old resolvconf back + defer func() { +- if err := ioutil.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil { + c.Fatal(err) + } + }() + +- resolvConf, err := ioutil.ReadFile("/etc/resolv.conf") ++ resolvConf, err := os.ReadFile("/etc/resolv.conf") + if os.IsNotExist(err) { + c.Fatalf("/etc/resolv.conf does not exist") + } +@@ -1430,7 +1429,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + tmpLocalhostResolvConf := []byte("nameserver 127.0.0.1") + + // take a copy of resolv.conf for restoring after test completes +- resolvConfSystem, err := ioutil.ReadFile("/etc/resolv.conf") ++ resolvConfSystem, err := os.ReadFile("/etc/resolv.conf") + if err != nil { + c.Fatal(err) + } +@@ -1448,7 +1447,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + + // cleanup + defer func() { +- if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { + c.Fatal(err) + } + }() +@@ -1458,7 +1457,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + containerID1 := getIDByName(c, "first") + + // replace resolv.conf with our temporary copy +- if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { + c.Fatal(err) + } + +@@ -1472,7 +1471,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + } + + /* // make a change to resolv.conf (in this case replacing our tmp copy with orig copy) +- if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { + c.Fatal(err) + } */ + // 2. test that a restarting container does not receive resolv.conf updates +@@ -1481,7 +1480,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + containerID2 := getIDByName(c, "second") + + // make a change to resolv.conf (in this case replacing our tmp copy with orig copy) +- if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { + c.Fatal(err) + } + +@@ -1499,7 +1498,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + runningContainerID := strings.TrimSpace(out) + + // replace resolv.conf +- if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { + c.Fatal(err) + } + +@@ -1523,7 +1522,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + // host resolv.conf before updating container's resolv.conf copies + + // replace resolv.conf with a localhost-only nameserver copy +- if err = ioutil.WriteFile("/etc/resolv.conf", tmpLocalhostResolvConf, 0644); err != nil { ++ if err = os.WriteFile("/etc/resolv.conf", tmpLocalhostResolvConf, 0644); err != nil { + c.Fatal(err) + } + +@@ -1542,7 +1541,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + // of containers' resolv.conf. + + // Restore the original resolv.conf +- if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { + c.Fatal(err) + } + +@@ -1551,7 +1550,7 @@ func (s *DockerSuite) TestRunResolvconfUpdate(c *testing.T) { + containerID3 := getIDByName(c, "third") + + // Create a modified resolv.conf.aside and override resolv.conf with it +- if err := ioutil.WriteFile("/etc/resolv.conf.aside", tmpResolvConf, 0644); err != nil { ++ if err := os.WriteFile("/etc/resolv.conf.aside", tmpResolvConf, 0644); err != nil { + c.Fatal(err) + } + +@@ -1885,7 +1884,7 @@ func (s *DockerSuite) TestRunBindMounts(c *testing.T) { + + prefix, _ := getPrefixAndSlashFromDaemonPlatform() + +- tmpDir, err := ioutil.TempDir("", "docker-test-container") ++ tmpDir, err := os.MkdirTemp("", "docker-test-container") + if err != nil { + c.Fatal(err) + } +@@ -1932,7 +1931,7 @@ func (s *DockerSuite) TestRunCidFileCleanupIfEmpty(c *testing.T) { + // Skip on Windows. Base image on Windows has a CMD set in the image. + testRequires(c, DaemonIsLinux) + +- tmpDir, err := ioutil.TempDir("", "TestRunCidFile") ++ tmpDir, err := os.MkdirTemp("", "TestRunCidFile") + if err != nil { + c.Fatal(err) + } +@@ -1960,7 +1959,7 @@ func (s *DockerSuite) TestRunCidFileCleanupIfEmpty(c *testing.T) { + // sudo docker run --cidfile /tmp/docker_tesc.cid ubuntu echo "test" + // TestRunCidFile tests that run --cidfile returns the longid + func (s *DockerSuite) TestRunCidFileCheckIDLength(c *testing.T) { +- tmpDir, err := ioutil.TempDir("", "TestRunCidFile") ++ tmpDir, err := os.MkdirTemp("", "TestRunCidFile") + if err != nil { + c.Fatal(err) + } +@@ -1970,7 +1969,7 @@ func (s *DockerSuite) TestRunCidFileCheckIDLength(c *testing.T) { + out, _ := dockerCmd(c, "run", "-d", "--cidfile", tmpCidFile, "busybox", "true") + + id := strings.TrimSpace(out) +- buffer, err := ioutil.ReadFile(tmpCidFile) ++ buffer, err := os.ReadFile(tmpCidFile) + if err != nil { + c.Fatal(err) + } +@@ -2081,13 +2080,13 @@ func (s *DockerSuite) TestRunMountOrdering(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux, NotUserNamespace) + prefix, _ := getPrefixAndSlashFromDaemonPlatform() + +- tmpDir, err := ioutil.TempDir("", "docker_nested_mount_test") ++ tmpDir, err := os.MkdirTemp("", "docker_nested_mount_test") + if err != nil { + c.Fatal(err) + } + defer os.RemoveAll(tmpDir) + +- tmpDir2, err := ioutil.TempDir("", "docker_nested_mount_test2") ++ tmpDir2, err := os.MkdirTemp("", "docker_nested_mount_test2") + if err != nil { + c.Fatal(err) + } +@@ -2099,15 +2098,15 @@ func (s *DockerSuite) TestRunMountOrdering(c *testing.T) { + c.Fatalf("failed to mkdir at %s - %s", fooDir, err) + } + +- if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", fooDir), []byte{}, 0644); err != nil { ++ if err := os.WriteFile(fmt.Sprintf("%s/touch-me", fooDir), []byte{}, 0644); err != nil { + c.Fatal(err) + } + +- if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", tmpDir), []byte{}, 0644); err != nil { ++ if err := os.WriteFile(fmt.Sprintf("%s/touch-me", tmpDir), []byte{}, 0644); err != nil { + c.Fatal(err) + } + +- if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", tmpDir2), []byte{}, 0644); err != nil { ++ if err := os.WriteFile(fmt.Sprintf("%s/touch-me", tmpDir2), []byte{}, 0644); err != nil { + c.Fatal(err) + } + +@@ -2126,7 +2125,7 @@ func (s *DockerSuite) TestRunReuseBindVolumeThatIsSymlink(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux, NotUserNamespace) + prefix, _ := getPrefixAndSlashFromDaemonPlatform() + +- tmpDir, err := ioutil.TempDir(os.TempDir(), "testlink") ++ tmpDir, err := os.MkdirTemp(os.TempDir(), "testlink") + if err != nil { + c.Fatal(err) + } +@@ -4079,7 +4078,7 @@ func (s *DockerSuite) TestRunCredentialSpecWellFormed(c *testing.T) { + func (s *DockerSuite) TestRunDuplicateMount(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux, NotUserNamespace) + +- tmpFile, err := ioutil.TempFile("", "touch-me") ++ tmpFile, err := os.CreateTemp("", "touch-me") + assert.NilError(c, err) + defer tmpFile.Close() + +@@ -4211,7 +4210,7 @@ func (s *delayedReader) Read([]byte) (int, error) { + // #28823 (originally #28639) + func (s *DockerSuite) TestRunMountReadOnlyDevShm(c *testing.T) { + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux, NotUserNamespace) +- emptyDir, err := ioutil.TempDir("", "test-read-only-dev-shm") ++ emptyDir, err := os.MkdirTemp("", "test-read-only-dev-shm") + assert.NilError(c, err) + defer os.RemoveAll(emptyDir) + out, _, err := dockerCmdWithError("run", "--rm", "--read-only", +@@ -4225,7 +4224,7 @@ func (s *DockerSuite) TestRunMount(c *testing.T) { + testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon, NotUserNamespace) + + // mnt1, mnt2, and testCatFooBar are commonly used in multiple test cases +- tmpDir, err := ioutil.TempDir("", "mount") ++ tmpDir, err := os.MkdirTemp("", "mount") + if err != nil { + c.Fatal(err) + } +@@ -4237,10 +4236,10 @@ func (s *DockerSuite) TestRunMount(c *testing.T) { + if err := os.Mkdir(mnt2, 0755); err != nil { + c.Fatal(err) + } +- if err := ioutil.WriteFile(path.Join(mnt1, "test1"), []byte("test1"), 0644); err != nil { ++ if err := os.WriteFile(path.Join(mnt1, "test1"), []byte("test1"), 0644); err != nil { + c.Fatal(err) + } +- if err := ioutil.WriteFile(path.Join(mnt2, "test2"), []byte("test2"), 0644); err != nil { ++ if err := os.WriteFile(path.Join(mnt2, "test2"), []byte("test2"), 0644); err != nil { + c.Fatal(err) + } + testCatFooBar := func(cName string) error { +diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go +index b67d15da5d..f11a8891a3 100644 +--- a/integration-cli/docker_cli_run_unix_test.go ++++ b/integration-cli/docker_cli_run_unix_test.go +@@ -8,7 +8,6 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -63,7 +62,7 @@ func (s *DockerSuite) TestRunRedirectStdout(c *testing.T) { + func (s *DockerSuite) TestRunWithVolumesIsRecursive(c *testing.T) { + // /tmp gets permission denied + testRequires(c, NotUserNamespace, testEnv.IsLocalDaemon) +- tmpDir, err := ioutil.TempDir("", "docker_recursive_mount_test") ++ tmpDir, err := os.MkdirTemp("", "docker_recursive_mount_test") + assert.NilError(c, err) + + defer os.RemoveAll(tmpDir) +@@ -73,7 +72,7 @@ func (s *DockerSuite) TestRunWithVolumesIsRecursive(c *testing.T) { + assert.Assert(c, os.MkdirAll(tmpfsDir, 0777) == nil, "failed to mkdir at %s", tmpfsDir) + assert.Assert(c, mount.Mount("tmpfs", tmpfsDir, "tmpfs", "") == nil, "failed to create a tmpfs mount at %s", tmpfsDir) + +- f, err := ioutil.TempFile(tmpfsDir, "touch-me") ++ f, err := os.CreateTemp(tmpfsDir, "touch-me") + assert.NilError(c, err) + defer f.Close() + +@@ -246,7 +245,7 @@ func (s *DockerSuite) TestRunAttachDetachFromConfig(c *testing.T) { + // Setup config + homeKey := homedir.Key() + homeVal := homedir.Get() +- tmpDir, err := ioutil.TempDir("", "fake-home") ++ tmpDir, err := os.MkdirTemp("", "fake-home") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir) + +@@ -261,7 +260,7 @@ func (s *DockerSuite) TestRunAttachDetachFromConfig(c *testing.T) { + "detachKeys": "ctrl-a,a" + }` + +- err = ioutil.WriteFile(tmpCfg, []byte(data), 0600) ++ err = os.WriteFile(tmpCfg, []byte(data), 0600) + assert.NilError(c, err) + + // Then do the work +@@ -329,7 +328,7 @@ func (s *DockerSuite) TestRunAttachDetachKeysOverrideConfig(c *testing.T) { + // Setup config + homeKey := homedir.Key() + homeVal := homedir.Get() +- tmpDir, err := ioutil.TempDir("", "fake-home") ++ tmpDir, err := os.MkdirTemp("", "fake-home") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir) + +@@ -344,7 +343,7 @@ func (s *DockerSuite) TestRunAttachDetachKeysOverrideConfig(c *testing.T) { + "detachKeys": "ctrl-e,e" + }` + +- err = ioutil.WriteFile(tmpCfg, []byte(data), 0600) ++ err = os.WriteFile(tmpCfg, []byte(data), 0600) + assert.NilError(c, err) + + // Then do the work +@@ -780,7 +779,7 @@ func (s *DockerSuite) TestRunWithShmSize(c *testing.T) { + } + + func (s *DockerSuite) TestRunTmpfsMountsEnsureOrdered(c *testing.T) { +- tmpFile, err := ioutil.TempFile("", "test") ++ tmpFile, err := os.CreateTemp("", "test") + assert.NilError(c, err) + defer tmpFile.Close() + out, _ := dockerCmd(c, "run", "--tmpfs", "/run", "-v", tmpFile.Name()+":/run/test", "busybox", "ls", "/run") +@@ -900,7 +899,7 @@ func (s *DockerSuite) TestRunSeccompProfileDenyUnshare(c *testing.T) { + } + ] + }` +- tmpFile, err := ioutil.TempFile("", "profile.json") ++ tmpFile, err := os.CreateTemp("", "profile.json") + if err != nil { + c.Fatal(err) + } +@@ -937,7 +936,7 @@ func (s *DockerSuite) TestRunSeccompProfileDenyChmod(c *testing.T) { + } + ] + }` +- tmpFile, err := ioutil.TempFile("", "profile.json") ++ tmpFile, err := os.CreateTemp("", "profile.json") + assert.NilError(c, err) + defer tmpFile.Close() + +@@ -972,7 +971,7 @@ func (s *DockerSuite) TestRunSeccompProfileDenyUnshareUserns(c *testing.T) { + } + ] + }`, uint64(0x10000000)) +- tmpFile, err := ioutil.TempFile("", "profile.json") ++ tmpFile, err := os.CreateTemp("", "profile.json") + if err != nil { + c.Fatal(err) + } +@@ -1349,7 +1348,7 @@ func (s *DockerSuite) TestRunDeviceSymlink(c *testing.T) { + } + + // Create a temporary directory to create symlink +- tmpDir, err := ioutil.TempDir("", "docker_device_follow_symlink_tests") ++ tmpDir, err := os.MkdirTemp("", "docker_device_follow_symlink_tests") + assert.NilError(c, err) + + defer os.RemoveAll(tmpDir) +@@ -1362,7 +1361,7 @@ func (s *DockerSuite) TestRunDeviceSymlink(c *testing.T) { + // Create a temporary file "temp" inside tmpDir, write some data to "tmpDir/temp", + // then create a symlink "tmpDir/file" to the temporary file "tmpDir/temp". + tmpFile := filepath.Join(tmpDir, "temp") +- err = ioutil.WriteFile(tmpFile, []byte("temp"), 0666) ++ err = os.WriteFile(tmpFile, []byte("temp"), 0666) + assert.NilError(c, err) + symFile := filepath.Join(tmpDir, "file") + err = os.Symlink(tmpFile, symFile) +@@ -1440,7 +1439,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNewFormat(c *testing.T) { + } + ] + }` +- tmpFile, err := ioutil.TempFile("", "profile.json") ++ tmpFile, err := os.CreateTemp("", "profile.json") + assert.NilError(c, err) + defer tmpFile.Close() + _, err = tmpFile.Write([]byte(jsonData)) +@@ -1466,7 +1465,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNoNameAndNames(c *testing.T) { + } + ] + }` +- tmpFile, err := ioutil.TempFile("", "profile.json") ++ tmpFile, err := os.CreateTemp("", "profile.json") + assert.NilError(c, err) + defer tmpFile.Close() + _, err = tmpFile.Write([]byte(jsonData)) +@@ -1503,7 +1502,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNoArchAndArchMap(c *testing.T) { + } + ] + }` +- tmpFile, err := ioutil.TempFile("", "profile.json") ++ tmpFile, err := os.CreateTemp("", "profile.json") + assert.NilError(c, err) + defer tmpFile.Close() + _, err = tmpFile.Write([]byte(jsonData)) +@@ -1536,7 +1535,7 @@ func (s *DockerDaemonSuite) TestRunWithDaemonDefaultSeccompProfile(c *testing.T) + } + ] + }` +- tmpFile, err := ioutil.TempFile("", "profile.json") ++ tmpFile, err := os.CreateTemp("", "profile.json") + assert.NilError(c, err) + defer tmpFile.Close() + _, err = tmpFile.Write([]byte(jsonData)) +diff --git a/integration-cli/docker_cli_save_load_test.go b/integration-cli/docker_cli_save_load_test.go +index 5f32d1c1d2..eac6fb054c 100644 +--- a/integration-cli/docker_cli_save_load_test.go ++++ b/integration-cli/docker_cli_save_load_test.go +@@ -5,7 +5,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -262,7 +261,7 @@ func (s *DockerSuite) TestSaveDirectoryPermissions(c *testing.T) { + layerEntriesAUFS := []string{"./", ".wh..wh.aufs", ".wh..wh.orph/", ".wh..wh.plnk/", "opt/", "opt/a/", "opt/a/b/", "opt/a/b/c"} + + name := "save-directory-permissions" +- tmpDir, err := ioutil.TempDir("", "save-layers-with-directories") ++ tmpDir, err := os.MkdirTemp("", "save-layers-with-directories") + assert.Assert(c, err == nil, "failed to create temporary directory: %s", err) + extractionDirectory := filepath.Join(tmpDir, "image-extraction-dir") + os.Mkdir(extractionDirectory, 0777) +@@ -278,7 +277,7 @@ func (s *DockerSuite) TestSaveDirectoryPermissions(c *testing.T) { + ) + assert.NilError(c, err, "failed to save and extract image: %s", out) + +- dirs, err := ioutil.ReadDir(extractionDirectory) ++ dirs, err := os.ReadDir(extractionDirectory) + assert.NilError(c, err, "failed to get a listing of the layer directories: %s", err) + + found := false +@@ -358,7 +357,7 @@ func (s *DockerSuite) TestSaveLoadParents(c *testing.T) { + idFoo := makeImage("busybox", "foo") + idBar := makeImage(idFoo, "bar") + +- tmpDir, err := ioutil.TempDir("", "save-load-parents") ++ tmpDir, err := os.MkdirTemp("", "save-load-parents") + assert.NilError(c, err) + defer os.RemoveAll(tmpDir) + +diff --git a/integration-cli/docker_cli_save_load_unix_test.go b/integration-cli/docker_cli_save_load_unix_test.go +index 0554fbe49f..89776b9263 100644 +--- a/integration-cli/docker_cli_save_load_unix_test.go ++++ b/integration-cli/docker_cli_save_load_unix_test.go +@@ -6,7 +6,6 @@ package main + import ( + "context" + "fmt" +- "io/ioutil" + "os" + "os/exec" + "strings" +@@ -28,7 +27,7 @@ func (s *DockerSuite) TestSaveAndLoadRepoStdout(c *testing.T) { + before, _ := dockerCmd(c, "commit", name, repoName) + before = strings.TrimRight(before, "\n") + +- tmpFile, err := ioutil.TempFile("", "foobar-save-load-test.tar") ++ tmpFile, err := os.CreateTemp("", "foobar-save-load-test.tar") + assert.NilError(c, err) + defer os.Remove(tmpFile.Name()) + +diff --git a/integration-cli/docker_cli_sni_test.go b/integration-cli/docker_cli_sni_test.go +index 9e086b546a..90e4f095d5 100644 +--- a/integration-cli/docker_cli_sni_test.go ++++ b/integration-cli/docker_cli_sni_test.go +@@ -2,7 +2,7 @@ package main + + import ( + "fmt" +- "io/ioutil" ++ "io" + "log" + "net/http" + "net/http/httptest" +@@ -25,7 +25,7 @@ func (s *DockerSuite) TestClientSetsTLSServerName(c *testing.T) { + })) + defer virtualHostServer.Close() + // discard TLS handshake errors written by default to os.Stderr +- virtualHostServer.Config.ErrorLog = log.New(ioutil.Discard, "", 0) ++ virtualHostServer.Config.ErrorLog = log.New(io.Discard, "", 0) + + u, err := url.Parse(virtualHostServer.URL) + assert.NilError(c, err) +diff --git a/integration-cli/docker_cli_swarm_test.go b/integration-cli/docker_cli_swarm_test.go +index fcbb3309dc..fc540853f2 100644 +--- a/integration-cli/docker_cli_swarm_test.go ++++ b/integration-cli/docker_cli_swarm_test.go +@@ -9,7 +9,6 @@ import ( + "encoding/json" + "encoding/pem" + "fmt" +- "io/ioutil" + "net/http" + "net/http/httptest" + "os" +@@ -63,7 +62,7 @@ func (s *DockerSwarmSuite) TestSwarmUpdate(c *testing.T) { + "--external-ca", "protocol=cfssl,url=https://somethingelse.org,cacert=fixtures/https/ca.pem"), + cli.Daemon(d)).Assert(c, icmd.Success) + +- expected, err := ioutil.ReadFile("fixtures/https/ca.pem") ++ expected, err := os.ReadFile("fixtures/https/ca.pem") + assert.NilError(c, err) + + spec = getSpec() +@@ -109,7 +108,7 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *testing.T) { + "--external-ca", "protocol=cfssl,url=https://somethingelse.org,cacert=fixtures/https/ca.pem"), + cli.Daemon(d)).Assert(c, icmd.Success) + +- expected, err := ioutil.ReadFile("fixtures/https/ca.pem") ++ expected, err := os.ReadFile("fixtures/https/ca.pem") + assert.NilError(c, err) + + spec := getSpec() +@@ -781,11 +780,11 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr + assert.NilError(c, err) + + fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv) +- err = ioutil.WriteFile(fileName, []byte(url), 0644) ++ err = os.WriteFile(fileName, []byte(url), 0644) + assert.NilError(c, err) + + ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv) +- err = ioutil.WriteFile(ipamFileName, []byte(url), 0644) ++ err = os.WriteFile(ipamFileName, []byte(url), 0644) + assert.NilError(c, err) + } + +@@ -812,7 +811,7 @@ func (s *DockerSwarmSuite) TestSwarmServiceEnvFile(c *testing.T) { + d := s.AddDaemon(c, true, true) + + path := filepath.Join(d.Folder, "env.txt") +- err := ioutil.WriteFile(path, []byte("VAR1=A\nVAR2=A\n"), 0644) ++ err := os.WriteFile(path, []byte("VAR1=A\nVAR2=A\n"), 0644) + assert.NilError(c, err) + + name := "worker" +@@ -986,7 +985,7 @@ func getNodeStatus(c *testing.T, d *daemon.Daemon) swarm.LocalNodeState { + + func checkKeyIsEncrypted(d *daemon.Daemon) func(*testing.T) (interface{}, string) { + return func(c *testing.T) (interface{}, string) { +- keyBytes, err := ioutil.ReadFile(filepath.Join(d.Folder, "root", "swarm", "certificates", "swarm-node.key")) ++ keyBytes, err := os.ReadFile(filepath.Join(d.Folder, "root", "swarm", "certificates", "swarm-node.key")) + if err != nil { + return fmt.Errorf("error reading key: %v", err), "" + } +@@ -1216,7 +1215,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinPromoteLocked(c *testing.T) { + // is set to autolock) + poll.WaitOn(c, pollCheck(c, d3.CheckControlAvailable, checker.False()), poll.WithTimeout(defaultReconciliationTimeout)) + poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) { +- certBytes, err := ioutil.ReadFile(filepath.Join(d3.Folder, "root", "swarm", "certificates", "swarm-node.crt")) ++ certBytes, err := os.ReadFile(filepath.Join(d3.Folder, "root", "swarm", "certificates", "swarm-node.crt")) + if err != nil { + return "", fmt.Sprintf("error: %v", err) + } +diff --git a/integration-cli/docker_cli_userns_test.go b/integration-cli/docker_cli_userns_test.go +index 7084f0e836..5c048c1f33 100644 +--- a/integration-cli/docker_cli_userns_test.go ++++ b/integration-cli/docker_cli_userns_test.go +@@ -5,7 +5,6 @@ package main + + import ( + "fmt" +- "io/ioutil" + "os" + "os/exec" + "path" +@@ -27,7 +26,7 @@ func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *testing.T) { + + s.d.StartWithBusybox(c, "--userns-remap", "default") + +- tmpDir, err := ioutil.TempDir("", "userns") ++ tmpDir, err := os.MkdirTemp("", "userns") + assert.NilError(c, err) + + defer os.RemoveAll(tmpDir) +diff --git a/integration-cli/docker_cli_v2_only_test.go b/integration-cli/docker_cli_v2_only_test.go +index 1b8e468dc4..5620350fa6 100644 +--- a/integration-cli/docker_cli_v2_only_test.go ++++ b/integration-cli/docker_cli_v2_only_test.go +@@ -2,7 +2,6 @@ package main + + import ( + "fmt" +- "io/ioutil" + "net/http" + "os" + "testing" +@@ -12,11 +11,11 @@ import ( + ) + + func makefile(path string, contents string) (string, error) { +- f, err := ioutil.TempFile(path, "tmp") ++ f, err := os.CreateTemp(path, "tmp") + if err != nil { + return "", err + } +- err = ioutil.WriteFile(f.Name(), []byte(contents), os.ModePerm) ++ err = os.WriteFile(f.Name(), []byte(contents), os.ModePerm) + if err != nil { + return "", err + } +@@ -42,7 +41,7 @@ func (s *DockerRegistrySuite) TestV2Only(c *testing.T) { + + s.d.Start(c, "--insecure-registry", reg.URL()) + +- tmp, err := ioutil.TempDir("", "integration-cli-") ++ tmp, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + defer os.RemoveAll(tmp) + +diff --git a/integration-cli/docker_cli_volume_test.go b/integration-cli/docker_cli_volume_test.go +index 0218a8c9dc..b7424c82af 100644 +--- a/integration-cli/docker_cli_volume_test.go ++++ b/integration-cli/docker_cli_volume_test.go +@@ -3,7 +3,6 @@ package main + import ( + "context" + "fmt" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -94,11 +93,11 @@ func (s *DockerSuite) TestVolumeLsFormatDefaultFormat(c *testing.T) { + config := `{ + "volumesFormat": "{{ .Name }} default" + }` +- d, err := ioutil.TempDir("", "integration-cli-") ++ d, err := os.MkdirTemp("", "integration-cli-") + assert.NilError(c, err) + defer os.RemoveAll(d) + +- err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) ++ err = os.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) + assert.NilError(c, err) + + out, _ := dockerCmd(c, "--config", d, "volume", "ls") +diff --git a/integration-cli/docker_utils_test.go b/integration-cli/docker_utils_test.go +index f1791f5006..5ae3aa44ea 100644 +--- a/integration-cli/docker_utils_test.go ++++ b/integration-cli/docker_utils_test.go +@@ -6,7 +6,6 @@ import ( + "errors" + "fmt" + "io" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -205,7 +204,7 @@ func writeFile(dst, content string, c *testing.T) { + // Fail the test when error occurs. + func readFile(src string, c *testing.T) (content string) { + c.Helper() +- data, err := ioutil.ReadFile(src) ++ data, err := os.ReadFile(src) + assert.NilError(c, err) + + return string(data) +@@ -233,7 +232,7 @@ func readContainerFile(c *testing.T, containerID, filename string) []byte { + assert.NilError(c, err) + defer f.Close() + +- content, err := ioutil.ReadAll(f) ++ content, err := io.ReadAll(f) + assert.NilError(c, err) + return content + } +@@ -303,12 +302,12 @@ func appendBaseEnv(isTLS bool, env ...string) []string { + + func createTmpFile(c *testing.T, content string) string { + c.Helper() +- f, err := ioutil.TempFile("", "testfile") ++ f, err := os.CreateTemp("", "testfile") + assert.NilError(c, err) + + filename := f.Name() + +- err = ioutil.WriteFile(filename, []byte(content), 0644) ++ err = os.WriteFile(filename, []byte(content), 0644) + assert.NilError(c, err) + + return filename +diff --git a/integration-cli/fixtures_linux_daemon_test.go b/integration-cli/fixtures_linux_daemon_test.go +index aa301cb001..b91b510c1f 100644 +--- a/integration-cli/fixtures_linux_daemon_test.go ++++ b/integration-cli/fixtures_linux_daemon_test.go +@@ -2,7 +2,6 @@ package main + + import ( + "fmt" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -29,7 +28,7 @@ func ensureSyscallTest(c *testing.T) { + return + } + +- tmp, err := ioutil.TempDir("", "syscall-test-build") ++ tmp, err := os.MkdirTemp("", "syscall-test-build") + assert.NilError(c, err, "couldn't create temp dir") + defer os.RemoveAll(tmp) + +@@ -52,7 +51,7 @@ func ensureSyscallTest(c *testing.T) { + FROM debian:bullseye-slim + COPY . /usr/bin/ + `) +- err = ioutil.WriteFile(dockerFile, content, 0600) ++ err = os.WriteFile(dockerFile, content, 0600) + assert.NilError(c, err) + + var buildArgs []string +@@ -92,7 +91,7 @@ func ensureNNPTest(c *testing.T) { + return + } + +- tmp, err := ioutil.TempDir("", "docker-nnp-test") ++ tmp, err := os.MkdirTemp("", "docker-nnp-test") + assert.NilError(c, err) + + gcc, err := exec.LookPath("gcc") +@@ -107,7 +106,7 @@ func ensureNNPTest(c *testing.T) { + COPY . /usr/bin + RUN chmod +s /usr/bin/nnp-test + ` +- err = ioutil.WriteFile(dockerfile, []byte(content), 0600) ++ err = os.WriteFile(dockerfile, []byte(content), 0600) + assert.NilError(c, err, "could not write Dockerfile for nnp-test image") + + var buildArgs []string +diff --git a/integration-cli/requirements_test.go b/integration-cli/requirements_test.go +index 8d5c64fe18..fc3df5cffe 100644 +--- a/integration-cli/requirements_test.go ++++ b/integration-cli/requirements_test.go +@@ -3,7 +3,6 @@ package main + import ( + "context" + "fmt" +- "io/ioutil" + "net/http" + "os" + "os/exec" +@@ -104,7 +103,7 @@ func Apparmor() bool { + if strings.HasPrefix(testEnv.DaemonInfo.OperatingSystem, "SUSE Linux Enterprise Server ") { + return false + } +- buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") ++ buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled") + return err == nil && len(buf) > 1 && buf[0] == 'Y' + } + +diff --git a/integration-cli/requirements_unix_test.go b/integration-cli/requirements_unix_test.go +index 7a22eea7e6..9e3df187d5 100644 +--- a/integration-cli/requirements_unix_test.go ++++ b/integration-cli/requirements_unix_test.go +@@ -5,7 +5,7 @@ package main + + import ( + "bytes" +- "io/ioutil" ++ "os" + "os/exec" + "strings" + +@@ -70,7 +70,7 @@ func bridgeNfIptables() bool { + } + + func unprivilegedUsernsClone() bool { +- content, err := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone") ++ content, err := os.ReadFile("/proc/sys/kernel/unprivileged_userns_clone") + return err != nil || !strings.Contains(string(content), "0") + } + +diff --git a/integration/build/build_session_test.go b/integration/build/build_session_test.go +index 7c626416a1..0781d50a0f 100644 +--- a/integration/build/build_session_test.go ++++ b/integration/build/build_session_test.go +@@ -2,7 +2,7 @@ package build + + import ( + "context" +- "io/ioutil" ++ "io" + "net" + "net/http" + "strings" +@@ -115,7 +115,7 @@ func testBuildWithSession(t *testing.T, client dclient.APIClient, daemonHost str + request.Host(daemonHost), + request.Method(http.MethodPost), + request.With(func(req *http.Request) error { +- req.Body = ioutil.NopCloser(strings.NewReader(dockerfile)) ++ req.Body = io.NopCloser(strings.NewReader(dockerfile)) + return nil + }), + ) +diff --git a/integration/build/build_squash_test.go b/integration/build/build_squash_test.go +index 54227b0c57..2e8e45604b 100644 +--- a/integration/build/build_squash_test.go ++++ b/integration/build/build_squash_test.go +@@ -4,7 +4,6 @@ import ( + "bytes" + "context" + "io" +- "io/ioutil" + "strings" + "testing" + +@@ -57,7 +56,7 @@ func TestBuildSquashParent(t *testing.T) { + Tags: []string{name}, + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + +@@ -75,7 +74,7 @@ func TestBuildSquashParent(t *testing.T) { + Tags: []string{name}, + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + +@@ -89,7 +88,7 @@ func TestBuildSquashParent(t *testing.T) { + assert.NilError(t, err) + + actualStdout := new(bytes.Buffer) +- actualStderr := ioutil.Discard ++ actualStderr := io.Discard + _, err = stdcopy.StdCopy(actualStdout, actualStderr, reader) + assert.NilError(t, err) + assert.Check(t, is.Equal(strings.TrimSpace(actualStdout.String()), "hello\nworld")) +diff --git a/integration/build/build_test.go b/integration/build/build_test.go +index b916a25206..62ef7075cb 100644 +--- a/integration/build/build_test.go ++++ b/integration/build/build_test.go +@@ -6,7 +6,7 @@ import ( + "context" + "encoding/json" + "io" +- "io/ioutil" ++ "os" + "strings" + "testing" + +@@ -144,7 +144,7 @@ func buildContainerIdsFilter(buildOutput io.Reader) (filters.Args, error) { + func TestBuildMultiStageCopy(t *testing.T) { + ctx := context.Background() + +- dockerfile, err := ioutil.ReadFile("testdata/Dockerfile." + t.Name()) ++ dockerfile, err := os.ReadFile("testdata/Dockerfile." + t.Name()) + assert.NilError(t, err) + + source := fakecontext.New(t, "", fakecontext.WithDockerfile(string(dockerfile))) +@@ -214,7 +214,7 @@ func TestBuildMultiStageParentConfig(t *testing.T) { + Tags: []string{imgName}, + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + +@@ -264,7 +264,7 @@ func TestBuildLabelWithTargets(t *testing.T) { + Target: "target-a", + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + +@@ -291,7 +291,7 @@ func TestBuildLabelWithTargets(t *testing.T) { + Target: "target-b", + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + +@@ -329,7 +329,7 @@ func TestBuildWithEmptyLayers(t *testing.T) { + ForceRemove: true, + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + } +@@ -541,9 +541,9 @@ func TestBuildWithEmptyDockerfile(t *testing.T) { + { + name: "empty-lines-dockerfile", + dockerfile: ` +- +- +- ++ ++ ++ + `, + expectedErr: "file with no instructions", + }, +@@ -585,7 +585,7 @@ func TestBuildPreserveOwnership(t *testing.T) { + + ctx := context.Background() + +- dockerfile, err := ioutil.ReadFile("testdata/Dockerfile." + t.Name()) ++ dockerfile, err := os.ReadFile("testdata/Dockerfile." + t.Name()) + assert.NilError(t, err) + + source := fakecontext.New(t, "", fakecontext.WithDockerfile(string(dockerfile))) +diff --git a/integration/build/build_userns_linux_test.go b/integration/build/build_userns_linux_test.go +index fc563c0348..dbb70f5961 100644 +--- a/integration/build/build_userns_linux_test.go ++++ b/integration/build/build_userns_linux_test.go +@@ -5,7 +5,6 @@ import ( + "bytes" + "context" + "io" +- "io/ioutil" + "os" + "strings" + "testing" +@@ -33,7 +32,7 @@ func TestBuildUserNamespaceValidateCapabilitiesAreV2(t *testing.T) { + + const imageTag = "capabilities:1.0" + +- tmp, err := ioutil.TempDir("", "integration-") ++ tmp, err := os.MkdirTemp("", "integration-") + assert.NilError(t, err) + defer os.RemoveAll(tmp) + +@@ -123,7 +122,7 @@ func TestBuildUserNamespaceValidateCapabilitiesAreV2(t *testing.T) { + defer logReader.Close() + + actualStdout := new(bytes.Buffer) +- actualStderr := ioutil.Discard ++ actualStderr := io.Discard + _, err = stdcopy.StdCopy(actualStdout, actualStderr, logReader) + assert.NilError(t, err) + if strings.TrimSpace(actualStdout.String()) != "/bin/sleep cap_net_bind_service=eip" { +diff --git a/integration/config/config_test.go b/integration/config/config_test.go +index 7f56fab112..36bc629db1 100644 +--- a/integration/config/config_test.go ++++ b/integration/config/config_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "context" + "encoding/json" +- "io/ioutil" ++ "os" + "path/filepath" + "sort" + "testing" +@@ -387,11 +387,11 @@ func TestConfigDaemonLibtrustID(t *testing.T) { + defer d.Stop(t) + + trustKey := filepath.Join(d.RootDir(), "key.json") +- err := ioutil.WriteFile(trustKey, []byte(`{"crv":"P-256","d":"dm28PH4Z4EbyUN8L0bPonAciAQa1QJmmyYd876mnypY","kid":"WTJ3:YSIP:CE2E:G6KJ:PSBD:YX2Y:WEYD:M64G:NU2V:XPZV:H2CR:VLUB","kty":"EC","x":"Mh5-JINSjaa_EZdXDttri255Z5fbCEOTQIZjAcScFTk","y":"eUyuAjfxevb07hCCpvi4Zi334Dy4GDWQvEToGEX4exQ"}`), 0644) ++ err := os.WriteFile(trustKey, []byte(`{"crv":"P-256","d":"dm28PH4Z4EbyUN8L0bPonAciAQa1QJmmyYd876mnypY","kid":"WTJ3:YSIP:CE2E:G6KJ:PSBD:YX2Y:WEYD:M64G:NU2V:XPZV:H2CR:VLUB","kty":"EC","x":"Mh5-JINSjaa_EZdXDttri255Z5fbCEOTQIZjAcScFTk","y":"eUyuAjfxevb07hCCpvi4Zi334Dy4GDWQvEToGEX4exQ"}`), 0644) + assert.NilError(t, err) + + config := filepath.Join(d.RootDir(), "daemon.json") +- err = ioutil.WriteFile(config, []byte(`{"deprecated-key-path": "`+trustKey+`"}`), 0644) ++ err = os.WriteFile(config, []byte(`{"deprecated-key-path": "`+trustKey+`"}`), 0644) + assert.NilError(t, err) + + d.Start(t, "--config-file", config) +diff --git a/integration/container/copy_test.go b/integration/container/copy_test.go +index cc5e457b94..c045b11fe3 100644 +--- a/integration/container/copy_test.go ++++ b/integration/container/copy_test.go +@@ -6,7 +6,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "os" + "testing" + +@@ -77,7 +76,7 @@ func TestCopyFromContainer(t *testing.T) { + ctx := context.Background() + apiClient := testEnv.APIClient() + +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(dir) + +@@ -95,7 +94,7 @@ func TestCopyFromContainer(t *testing.T) { + defer resp.Body.Close() + + var imageID string +- err = jsonmessage.DisplayJSONMessagesStream(resp.Body, ioutil.Discard, 0, false, func(msg jsonmessage.JSONMessage) { ++ err = jsonmessage.DisplayJSONMessagesStream(resp.Body, io.Discard, 0, false, func(msg jsonmessage.JSONMessage) { + var r types.BuildResult + assert.NilError(t, json.Unmarshal(*msg.Aux, &r)) + imageID = r.ID +@@ -147,7 +146,7 @@ func TestCopyFromContainer(t *testing.T) { + numFound++ + found[h.Name] = true + +- buf, err := ioutil.ReadAll(tr) ++ buf, err := io.ReadAll(tr) + if err == nil { + assert.Check(t, is.Equal(string(buf), expected)) + } +diff --git a/integration/container/daemon_linux_test.go b/integration/container/daemon_linux_test.go +index f4a944248b..1683c51fec 100644 +--- a/integration/container/daemon_linux_test.go ++++ b/integration/container/daemon_linux_test.go +@@ -4,7 +4,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "os" + "path/filepath" + "strconv" + "strings" +@@ -73,7 +73,7 @@ func TestContainerStartOnDaemonRestart(t *testing.T) { + } + + func getContainerdShimPid(t *testing.T, c types.ContainerJSON) int { +- statB, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", c.State.Pid)) ++ statB, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", c.State.Pid)) + assert.Check(t, err, "error looking up containerd-shim pid") + + // ppid is the 4th entry in `/proc/pid/stat` +@@ -206,7 +206,7 @@ func TestRestartDaemonWithRestartingContainer(t *testing.T) { + d.Stop(t) + + configPath := filepath.Join(d.Root, "containers", id, "config.v2.json") +- configBytes, err := ioutil.ReadFile(configPath) ++ configBytes, err := os.ReadFile(configPath) + assert.NilError(t, err) + + var c realcontainer.Container +@@ -219,7 +219,7 @@ func TestRestartDaemonWithRestartingContainer(t *testing.T) { + + configBytes, err = json.Marshal(&c) + assert.NilError(t, err) +- assert.NilError(t, ioutil.WriteFile(configPath, configBytes, 0600)) ++ assert.NilError(t, os.WriteFile(configPath, configBytes, 0600)) + + d.Start(t) + +diff --git a/integration/container/exec_test.go b/integration/container/exec_test.go +index 0394f52963..4b2301cbe0 100644 +--- a/integration/container/exec_test.go ++++ b/integration/container/exec_test.go +@@ -2,7 +2,7 @@ package container // import "github.com/docker/docker/integration/container" + + import ( + "context" +- "io/ioutil" ++ "io" + "testing" + "time" + +@@ -59,7 +59,7 @@ func TestExecWithCloseStdin(t *testing.T) { + go func() { + close(waitCh) + defer close(resCh) +- r, err := ioutil.ReadAll(resp.Reader) ++ r, err := io.ReadAll(resp.Reader) + + resCh <- struct { + content string +@@ -113,7 +113,7 @@ func TestExec(t *testing.T) { + ) + assert.NilError(t, err) + defer resp.Close() +- r, err := ioutil.ReadAll(resp.Reader) ++ r, err := io.ReadAll(resp.Reader) + assert.NilError(t, err) + out := string(r) + assert.NilError(t, err) +diff --git a/integration/container/ipcmode_linux_test.go b/integration/container/ipcmode_linux_test.go +index d5c415125c..030ec90179 100644 +--- a/integration/container/ipcmode_linux_test.go ++++ b/integration/container/ipcmode_linux_test.go +@@ -3,7 +3,6 @@ package container // import "github.com/docker/docker/integration/container" + import ( + "bufio" + "context" +- "io/ioutil" + "os" + "regexp" + "strings" +@@ -217,7 +216,7 @@ func TestAPIIpcModeHost(t *testing.T) { + _, err = container.Exec(ctx, client, name, []string{"sh", "-c", "printf covfefe > /dev/shm/." + name}) + assert.NilError(t, err) + // 2. check it's the same on the host +- bytes, err := ioutil.ReadFile("/dev/shm/." + name) ++ bytes, err := os.ReadFile("/dev/shm/." + name) + assert.NilError(t, err) + assert.Check(t, is.Equal("covfefe", string(bytes))) + // 3. clean up +diff --git a/integration/container/links_linux_test.go b/integration/container/links_linux_test.go +index 1bc424f10c..3f038d8b90 100644 +--- a/integration/container/links_linux_test.go ++++ b/integration/container/links_linux_test.go +@@ -2,7 +2,6 @@ package container // import "github.com/docker/docker/integration/container" + + import ( + "context" +- "io/ioutil" + "os" + "testing" + +@@ -18,7 +17,7 @@ func TestLinksEtcHostsContentMatch(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon) + skip.If(t, testEnv.IsRootless, "rootless mode has different view of /etc/hosts") + +- hosts, err := ioutil.ReadFile("/etc/hosts") ++ hosts, err := os.ReadFile("/etc/hosts") + skip.If(t, os.IsNotExist(err)) + + defer setupTest(t)() +diff --git a/integration/container/logs_test.go b/integration/container/logs_test.go +index 08ab25ee84..837c75ac08 100644 +--- a/integration/container/logs_test.go ++++ b/integration/container/logs_test.go +@@ -2,7 +2,7 @@ package container // import "github.com/docker/docker/integration/container" + + import ( + "context" +- "io/ioutil" ++ "io" + "testing" + + "github.com/docker/docker/api/types" +@@ -29,6 +29,6 @@ func TestLogsFollowTailEmpty(t *testing.T) { + } + assert.Check(t, err) + +- _, err = stdcopy.StdCopy(ioutil.Discard, ioutil.Discard, logs) ++ _, err = stdcopy.StdCopy(io.Discard, io.Discard, logs) + assert.Check(t, err) + } +diff --git a/integration/container/nat_test.go b/integration/container/nat_test.go +index aad5175fd5..5567e01ab3 100644 +--- a/integration/container/nat_test.go ++++ b/integration/container/nat_test.go +@@ -5,7 +5,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "net" + "strings" + "testing" +@@ -34,7 +33,7 @@ func TestNetworkNat(t *testing.T) { + assert.NilError(t, err) + defer conn.Close() + +- data, err := ioutil.ReadAll(conn) ++ data, err := io.ReadAll(conn) + assert.NilError(t, err) + assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data)))) + } +@@ -51,7 +50,7 @@ func TestNetworkLocalhostTCPNat(t *testing.T) { + assert.NilError(t, err) + defer conn.Close() + +- data, err := ioutil.ReadAll(conn) ++ data, err := io.ReadAll(conn) + assert.NilError(t, err) + assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data)))) + } +diff --git a/integration/image/pull_test.go b/integration/image/pull_test.go +index 7863f7a8ae..96def69395 100644 +--- a/integration/image/pull_test.go ++++ b/integration/image/pull_test.go +@@ -4,7 +4,6 @@ import ( + "context" + "encoding/json" + "io" +- "io/ioutil" + "os" + "path" + "testing" +@@ -151,7 +150,7 @@ func TestImagePullStoredfDigestForOtherRepo(t *testing.T) { + rdr, err := client.ImagePull(ctx, remote, types.ImagePullOptions{}) + assert.NilError(t, err) + defer rdr.Close() +- io.Copy(ioutil.Discard, rdr) ++ io.Copy(io.Discard, rdr) + + // Now, pull a totally different repo with a the same digest + rdr, err = client.ImagePull(ctx, path.Join(registry.DefaultURL, "other:image@"+desc.Digest.String()), types.ImagePullOptions{}) +diff --git a/integration/image/remove_unix_test.go b/integration/image/remove_unix_test.go +index b548275e7b..a5522f4c30 100644 +--- a/integration/image/remove_unix_test.go ++++ b/integration/image/remove_unix_test.go +@@ -6,7 +6,6 @@ package image // import "github.com/docker/docker/integration/image" + import ( + "context" + "io" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -76,7 +75,7 @@ func TestRemoveImageGarbageCollector(t *testing.T) { + Tags: []string{img}, + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + image, _, err := client.ImageInspectWithRaw(ctx, img) +@@ -114,7 +113,7 @@ func TestRemoveImageGarbageCollector(t *testing.T) { + assert.Assert(t, os.IsNotExist(err)) + + // Make sure that removal pending layers does not exist on layerdb either +- layerdbItems, _ := ioutil.ReadDir(filepath.Join(d.RootDir(), "/image/overlay2/layerdb/sha256")) ++ layerdbItems, _ := os.ReadDir(filepath.Join(d.RootDir(), "/image/overlay2/layerdb/sha256")) + for _, folder := range layerdbItems { + assert.Equal(t, false, strings.HasSuffix(folder.Name(), "-removing")) + } +diff --git a/integration/plugin/authz/authz_plugin_test.go b/integration/plugin/authz/authz_plugin_test.go +index 6cce66cd6c..3c8cfc6a65 100644 +--- a/integration/plugin/authz/authz_plugin_test.go ++++ b/integration/plugin/authz/authz_plugin_test.go +@@ -7,7 +7,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "net" + "net/http" + "net/http/httputil" +@@ -61,7 +60,7 @@ func setupTestV1(t *testing.T) func() { + assert.NilError(t, err) + + fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", testAuthZPlugin) +- err = ioutil.WriteFile(fileName, []byte(server.URL), 0644) ++ err = os.WriteFile(fileName, []byte(server.URL), 0644) + assert.NilError(t, err) + + return func() { +@@ -336,7 +335,7 @@ func TestAuthZPluginEnsureLoadImportWorking(t *testing.T) { + c := d.NewClientT(t) + ctx := context.Background() + +- tmp, err := ioutil.TempDir("", "test-authz-load-import") ++ tmp, err := os.MkdirTemp("", "test-authz-load-import") + assert.NilError(t, err) + defer os.RemoveAll(tmp) + +@@ -370,11 +369,11 @@ func TestAuthzPluginEnsureContainerCopyToFrom(t *testing.T) { + ctrl.resRes.Allow = true + d.StartWithBusybox(t, "--authorization-plugin="+testAuthZPlugin, "--authorization-plugin="+testAuthZPlugin) + +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(dir) + +- f, err := ioutil.TempFile(dir, "send") ++ f, err := os.CreateTemp(dir, "send") + assert.NilError(t, err) + defer f.Close() + +@@ -409,7 +408,7 @@ func TestAuthzPluginEnsureContainerCopyToFrom(t *testing.T) { + + rdr, _, err := c.CopyFromContainer(ctx, cID, "/test") + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, rdr) ++ _, err = io.Copy(io.Discard, rdr) + assert.NilError(t, err) + } + +diff --git a/integration/plugin/authz/authz_plugin_v2_test.go b/integration/plugin/authz/authz_plugin_v2_test.go +index f567f5a448..173d0a5df6 100644 +--- a/integration/plugin/authz/authz_plugin_v2_test.go ++++ b/integration/plugin/authz/authz_plugin_v2_test.go +@@ -6,7 +6,7 @@ package authz // import "github.com/docker/docker/integration/plugin/authz" + import ( + "context" + "fmt" +- "io/ioutil" ++ "io" + "os" + "strings" + "testing" +@@ -166,6 +166,6 @@ func pluginInstallGrantAllPermissions(client client.APIClient, name string) erro + // we have to read the response out here because the client API + // actually starts a goroutine which we can only be sure has + // completed when we get EOF from reading responseBody +- _, err = ioutil.ReadAll(responseReader) ++ _, err = io.ReadAll(responseReader) + return err + } +diff --git a/integration/plugin/authz/main_test.go b/integration/plugin/authz/main_test.go +index ff39d61372..b4e6564081 100644 +--- a/integration/plugin/authz/main_test.go ++++ b/integration/plugin/authz/main_test.go +@@ -6,7 +6,7 @@ package authz // import "github.com/docker/docker/integration/plugin/authz" + import ( + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "net/http/httptest" + "os" +@@ -77,7 +77,7 @@ func setupSuite() { + + mux.HandleFunc("/AuthZPlugin.AuthZReq", func(w http.ResponseWriter, r *http.Request) { + defer r.Body.Close() +- body, err := ioutil.ReadAll(r.Body) ++ body, err := io.ReadAll(r.Body) + if err != nil { + panic("could not read body for /AuthZPlugin.AuthZReq: " + err.Error()) + } +@@ -115,7 +115,7 @@ func setupSuite() { + + mux.HandleFunc("/AuthZPlugin.AuthZRes", func(w http.ResponseWriter, r *http.Request) { + defer r.Body.Close() +- body, err := ioutil.ReadAll(r.Body) ++ body, err := io.ReadAll(r.Body) + if err != nil { + panic("could not read body for /AuthZPlugin.AuthZRes: " + err.Error()) + } +diff --git a/integration/plugin/common/plugin_test.go b/integration/plugin/common/plugin_test.go +index 21add8f34c..2ba7fb0502 100644 +--- a/integration/plugin/common/plugin_test.go ++++ b/integration/plugin/common/plugin_test.go +@@ -6,7 +6,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net" + "net/http" + "os" +@@ -80,7 +79,7 @@ func TestPluginInstall(t *testing.T) { + assert.NilError(t, err) + defer rdr.Close() + +- _, err = io.Copy(ioutil.Discard, rdr) ++ _, err = io.Copy(io.Discard, rdr) + assert.NilError(t, err) + + _, _, err = client.PluginInspectWithRaw(ctx, repo) +@@ -109,7 +108,7 @@ func TestPluginInstall(t *testing.T) { + assert.NilError(t, err) + defer rdr.Close() + +- _, err = io.Copy(ioutil.Discard, rdr) ++ _, err = io.Copy(io.Discard, rdr) + assert.NilError(t, err) + + _, _, err = client.PluginInspectWithRaw(ctx, repo) +@@ -157,7 +156,7 @@ func TestPluginInstall(t *testing.T) { + assert.NilError(t, err) + defer rdr.Close() + +- _, err = io.Copy(ioutil.Discard, rdr) ++ _, err = io.Copy(io.Discard, rdr) + assert.NilError(t, err) + + _, _, err = client.PluginInspectWithRaw(ctx, repo) +@@ -171,7 +170,7 @@ func TestPluginsWithRuntimes(t *testing.T) { + skip.If(t, testEnv.IsRootless, "Test not supported on rootless due to buggy daemon setup in rootless mode due to daemon restart") + skip.If(t, testEnv.OSType == "windows") + +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(dir) + +@@ -201,7 +200,7 @@ func TestPluginsWithRuntimes(t *testing.T) { + exec runc $@ + `, dir) + +- assert.NilError(t, ioutil.WriteFile(p, []byte(script), 0777)) ++ assert.NilError(t, os.WriteFile(p, []byte(script), 0777)) + + type config struct { + Runtimes map[string]types.Runtime `json:"runtimes"` +@@ -214,7 +213,7 @@ func TestPluginsWithRuntimes(t *testing.T) { + }, + }) + configPath := filepath.Join(dir, "config.json") +- ioutil.WriteFile(configPath, cfg, 0644) ++ os.WriteFile(configPath, cfg, 0644) + + t.Run("No Args", func(t *testing.T) { + d.Restart(t, "--default-runtime=myrt", "--config-file="+configPath) +diff --git a/integration/plugin/graphdriver/external_test.go b/integration/plugin/graphdriver/external_test.go +index 87ce1b82d7..57fb27856d 100644 +--- a/integration/plugin/graphdriver/external_test.go ++++ b/integration/plugin/graphdriver/external_test.go +@@ -5,7 +5,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "net/http" + "net/http/httptest" + "os" +@@ -145,7 +144,7 @@ func setupPlugin(t *testing.T, ec map[string]*graphEventsCounter, ext string, mu + return nil + } + +- base, err := ioutil.TempDir("", name) ++ base, err := os.MkdirTemp("", name) + assert.NilError(t, err) + vfsProto, err := vfs.Init(base, []string{}, nil, nil) + assert.NilError(t, err, "error initializing graph driver") +@@ -349,7 +348,7 @@ func setupPlugin(t *testing.T, ec map[string]*graphEventsCounter, ext string, mu + assert.NilError(t, err) + + specFile := "/etc/docker/plugins/" + name + "." + ext +- err = ioutil.WriteFile(specFile, b, 0644) ++ err = os.WriteFile(specFile, b, 0644) + assert.NilError(t, err) + } + +@@ -397,7 +396,7 @@ func testGraphDriverPull(c client.APIClient, d *daemon.Daemon) func(*testing.T) + + r, err := c.ImagePull(ctx, "busybox:latest@sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209", types.ImagePullOptions{}) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, r) ++ _, err = io.Copy(io.Discard, r) + assert.NilError(t, err) + + container.Run(ctx, t, c, container.WithImage("busybox:latest@sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209")) +@@ -428,7 +427,7 @@ func TestGraphdriverPluginV2(t *testing.T) { + assert.NilError(t, err) + defer responseReader.Close() + // ensure it's done by waiting for EOF on the response +- _, err = io.Copy(ioutil.Discard, responseReader) ++ _, err = io.Copy(io.Discard, responseReader) + assert.NilError(t, err) + + // restart the daemon with the plugin set as the storage driver +diff --git a/integration/plugin/logging/cmd/discard/driver.go b/integration/plugin/logging/cmd/discard/driver.go +index e02b56e88f..bbdebaf443 100644 +--- a/integration/plugin/logging/cmd/discard/driver.go ++++ b/integration/plugin/logging/cmd/discard/driver.go +@@ -3,7 +3,6 @@ package main + import ( + "encoding/json" + "io" +- "io/ioutil" + "net/http" + "os" + "sync" +@@ -47,7 +46,7 @@ func handle(mux *http.ServeMux) { + d.logs[req.File] = f + d.mu.Unlock() + +- go io.Copy(ioutil.Discard, f) ++ go io.Copy(io.Discard, f) + respond(err, w) + }) + +diff --git a/integration/plugin/volumes/mounts_test.go b/integration/plugin/volumes/mounts_test.go +index 991b1e1105..c80c4cd79c 100644 +--- a/integration/plugin/volumes/mounts_test.go ++++ b/integration/plugin/volumes/mounts_test.go +@@ -2,7 +2,6 @@ package volumes + + import ( + "context" +- "io/ioutil" + "os" + "testing" + +@@ -28,7 +27,7 @@ func TestPluginWithDevMounts(t *testing.T) { + c := d.NewClientT(t) + ctx := context.Background() + +- testDir, err := ioutil.TempDir("", "test-dir") ++ testDir, err := os.MkdirTemp("", "test-dir") + assert.NilError(t, err) + defer os.RemoveAll(testDir) + +diff --git a/integration/service/create_test.go b/integration/service/create_test.go +index 1992a6e4ca..8335f894b8 100644 +--- a/integration/service/create_test.go ++++ b/integration/service/create_test.go +@@ -3,7 +3,7 @@ package service // import "github.com/docker/docker/integration/service" + import ( + "context" + "fmt" +- "io/ioutil" ++ "io" + "strings" + "testing" + "time" +@@ -289,7 +289,7 @@ func TestCreateServiceSecretFileMode(t *testing.T) { + assert.NilError(t, err) + defer body.Close() + +- content, err := ioutil.ReadAll(body) ++ content, err := io.ReadAll(body) + assert.NilError(t, err) + assert.Check(t, is.Contains(string(content), "-rwxrwxrwx")) + +@@ -346,7 +346,7 @@ func TestCreateServiceConfigFileMode(t *testing.T) { + assert.NilError(t, err) + defer body.Close() + +- content, err := ioutil.ReadAll(body) ++ content, err := io.ReadAll(body) + assert.NilError(t, err) + assert.Check(t, is.Contains(string(content), "-rwxrwxrwx")) + +diff --git a/integration/service/plugin_test.go b/integration/service/plugin_test.go +index 651c6dd057..33505990ca 100644 +--- a/integration/service/plugin_test.go ++++ b/integration/service/plugin_test.go +@@ -3,7 +3,6 @@ package service + import ( + "context" + "io" +- "io/ioutil" + "os" + "path" + "strings" +@@ -42,7 +41,7 @@ func TestServicePlugin(t *testing.T) { + assert.NilError(t, err) + r, err := apiclient.PluginPush(context.Background(), repo, "") + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, r) ++ _, err = io.Copy(io.Discard, r) + assert.NilError(t, err) + err = apiclient.PluginRemove(context.Background(), repo, types.PluginRemoveOptions{}) + assert.NilError(t, err) +@@ -50,7 +49,7 @@ func TestServicePlugin(t *testing.T) { + assert.NilError(t, err) + r, err = apiclient.PluginPush(context.Background(), repo2, "") + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, r) ++ _, err = io.Copy(io.Discard, r) + assert.NilError(t, err) + err = apiclient.PluginRemove(context.Background(), repo2, types.PluginRemoveOptions{}) + assert.NilError(t, err) +diff --git a/layer/empty.go b/layer/empty.go +index c81c702140..46fc571255 100644 +--- a/layer/empty.go ++++ b/layer/empty.go +@@ -5,7 +5,6 @@ import ( + "bytes" + "fmt" + "io" +- "io/ioutil" + ) + + // DigestSHA256EmptyTar is the canonical sha256 digest of empty tar file - +@@ -21,7 +20,7 @@ func (el *emptyLayer) TarStream() (io.ReadCloser, error) { + buf := new(bytes.Buffer) + tarWriter := tar.NewWriter(buf) + tarWriter.Close() +- return ioutil.NopCloser(buf), nil ++ return io.NopCloser(buf), nil + } + + func (el *emptyLayer) TarStreamFrom(p ChainID) (io.ReadCloser, error) { +diff --git a/layer/filestore.go b/layer/filestore.go +index 0c15cc9b96..37bc41d514 100644 +--- a/layer/filestore.go ++++ b/layer/filestore.go +@@ -5,7 +5,6 @@ import ( + "encoding/json" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "regexp" +@@ -143,7 +142,7 @@ func (fm *fileMetadataTransaction) String() string { + } + + func (fms *fileMetadataStore) GetSize(layer ChainID) (int64, error) { +- content, err := ioutil.ReadFile(fms.getLayerFilename(layer, "size")) ++ content, err := os.ReadFile(fms.getLayerFilename(layer, "size")) + if err != nil { + return 0, err + } +@@ -157,7 +156,7 @@ func (fms *fileMetadataStore) GetSize(layer ChainID) (int64, error) { + } + + func (fms *fileMetadataStore) GetParent(layer ChainID) (ChainID, error) { +- content, err := ioutil.ReadFile(fms.getLayerFilename(layer, "parent")) ++ content, err := os.ReadFile(fms.getLayerFilename(layer, "parent")) + if err != nil { + if os.IsNotExist(err) { + return "", nil +@@ -174,7 +173,7 @@ func (fms *fileMetadataStore) GetParent(layer ChainID) (ChainID, error) { + } + + func (fms *fileMetadataStore) GetDiffID(layer ChainID) (DiffID, error) { +- content, err := ioutil.ReadFile(fms.getLayerFilename(layer, "diff")) ++ content, err := os.ReadFile(fms.getLayerFilename(layer, "diff")) + if err != nil { + return "", err + } +@@ -188,7 +187,7 @@ func (fms *fileMetadataStore) GetDiffID(layer ChainID) (DiffID, error) { + } + + func (fms *fileMetadataStore) GetCacheID(layer ChainID) (string, error) { +- contentBytes, err := ioutil.ReadFile(fms.getLayerFilename(layer, "cache-id")) ++ contentBytes, err := os.ReadFile(fms.getLayerFilename(layer, "cache-id")) + if err != nil { + return "", err + } +@@ -202,7 +201,7 @@ func (fms *fileMetadataStore) GetCacheID(layer ChainID) (string, error) { + } + + func (fms *fileMetadataStore) GetDescriptor(layer ChainID) (distribution.Descriptor, error) { +- content, err := ioutil.ReadFile(fms.getLayerFilename(layer, "descriptor.json")) ++ content, err := os.ReadFile(fms.getLayerFilename(layer, "descriptor.json")) + if err != nil { + if os.IsNotExist(err) { + // only return empty descriptor to represent what is stored +@@ -240,25 +239,25 @@ func (fms *fileMetadataStore) SetMountID(mount string, mountID string) error { + if err := os.MkdirAll(fms.getMountDirectory(mount), 0755); err != nil { + return err + } +- return ioutil.WriteFile(fms.getMountFilename(mount, "mount-id"), []byte(mountID), 0644) ++ return os.WriteFile(fms.getMountFilename(mount, "mount-id"), []byte(mountID), 0644) + } + + func (fms *fileMetadataStore) SetInitID(mount string, init string) error { + if err := os.MkdirAll(fms.getMountDirectory(mount), 0755); err != nil { + return err + } +- return ioutil.WriteFile(fms.getMountFilename(mount, "init-id"), []byte(init), 0644) ++ return os.WriteFile(fms.getMountFilename(mount, "init-id"), []byte(init), 0644) + } + + func (fms *fileMetadataStore) SetMountParent(mount string, parent ChainID) error { + if err := os.MkdirAll(fms.getMountDirectory(mount), 0755); err != nil { + return err + } +- return ioutil.WriteFile(fms.getMountFilename(mount, "parent"), []byte(digest.Digest(parent).String()), 0644) ++ return os.WriteFile(fms.getMountFilename(mount, "parent"), []byte(digest.Digest(parent).String()), 0644) + } + + func (fms *fileMetadataStore) GetMountID(mount string) (string, error) { +- contentBytes, err := ioutil.ReadFile(fms.getMountFilename(mount, "mount-id")) ++ contentBytes, err := os.ReadFile(fms.getMountFilename(mount, "mount-id")) + if err != nil { + return "", err + } +@@ -272,7 +271,7 @@ func (fms *fileMetadataStore) GetMountID(mount string) (string, error) { + } + + func (fms *fileMetadataStore) GetInitID(mount string) (string, error) { +- contentBytes, err := ioutil.ReadFile(fms.getMountFilename(mount, "init-id")) ++ contentBytes, err := os.ReadFile(fms.getMountFilename(mount, "init-id")) + if err != nil { + if os.IsNotExist(err) { + return "", nil +@@ -289,7 +288,7 @@ func (fms *fileMetadataStore) GetInitID(mount string) (string, error) { + } + + func (fms *fileMetadataStore) GetMountParent(mount string) (ChainID, error) { +- content, err := ioutil.ReadFile(fms.getMountFilename(mount, "parent")) ++ content, err := os.ReadFile(fms.getMountFilename(mount, "parent")) + if err != nil { + if os.IsNotExist(err) { + return "", nil +@@ -308,7 +307,7 @@ func (fms *fileMetadataStore) GetMountParent(mount string) (ChainID, error) { + func (fms *fileMetadataStore) getOrphan() ([]roLayer, error) { + var orphanLayers []roLayer + for _, algorithm := range supportedAlgorithms { +- fileInfos, err := ioutil.ReadDir(filepath.Join(fms.root, string(algorithm))) ++ fileInfos, err := os.ReadDir(filepath.Join(fms.root, string(algorithm))) + if err != nil { + if os.IsNotExist(err) { + continue +@@ -330,7 +329,7 @@ func (fms *fileMetadataStore) getOrphan() ([]roLayer, error) { + } + + chainFile := filepath.Join(fms.root, string(algorithm), fi.Name(), "cache-id") +- contentBytes, err := ioutil.ReadFile(chainFile) ++ contentBytes, err := os.ReadFile(chainFile) + if err != nil { + if !os.IsNotExist(err) { + logrus.WithError(err).WithField("digest", dgst).Error("failed to read cache ID") +@@ -357,7 +356,7 @@ func (fms *fileMetadataStore) getOrphan() ([]roLayer, error) { + func (fms *fileMetadataStore) List() ([]ChainID, []string, error) { + var ids []ChainID + for _, algorithm := range supportedAlgorithms { +- fileInfos, err := ioutil.ReadDir(filepath.Join(fms.root, string(algorithm))) ++ fileInfos, err := os.ReadDir(filepath.Join(fms.root, string(algorithm))) + if err != nil { + if os.IsNotExist(err) { + continue +@@ -377,7 +376,7 @@ func (fms *fileMetadataStore) List() ([]ChainID, []string, error) { + } + } + +- fileInfos, err := ioutil.ReadDir(filepath.Join(fms.root, "mounts")) ++ fileInfos, err := os.ReadDir(filepath.Join(fms.root, "mounts")) + if err != nil { + if os.IsNotExist(err) { + return ids, []string{}, nil +@@ -398,7 +397,7 @@ func (fms *fileMetadataStore) List() ([]ChainID, []string, error) { + // Remove layerdb folder if that is marked for removal + func (fms *fileMetadataStore) Remove(layer ChainID, cache string) error { + dgst := digest.Digest(layer) +- files, err := ioutil.ReadDir(filepath.Join(fms.root, string(dgst.Algorithm()))) ++ files, err := os.ReadDir(filepath.Join(fms.root, string(dgst.Algorithm()))) + if err != nil { + return err + } +@@ -411,7 +410,7 @@ func (fms *fileMetadataStore) Remove(layer ChainID, cache string) error { + // requested cacheID + dir := filepath.Join(fms.root, string(dgst.Algorithm()), f.Name()) + chainFile := filepath.Join(dir, "cache-id") +- contentBytes, err := ioutil.ReadFile(chainFile) ++ contentBytes, err := os.ReadFile(chainFile) + if err != nil { + logrus.WithError(err).WithField("file", chainFile).Error("cannot get cache ID") + continue +diff --git a/layer/filestore_test.go b/layer/filestore_test.go +index 3af1904f48..926260aca0 100644 +--- a/layer/filestore_test.go ++++ b/layer/filestore_test.go +@@ -2,7 +2,6 @@ package layer // import "github.com/docker/docker/layer" + + import ( + "fmt" +- "io/ioutil" + "math/rand" + "os" + "path/filepath" +@@ -21,7 +20,7 @@ func randomLayerID(seed int64) ChainID { + } + + func newFileMetadataStore(t *testing.T) (*fileMetadataStore, string, func()) { +- td, err := ioutil.TempDir("", "layers-") ++ td, err := os.MkdirTemp("", "layers-") + if err != nil { + t.Fatal(err) + } +@@ -52,7 +51,7 @@ func TestCommitFailure(t *testing.T) { + fms, td, cleanup := newFileMetadataStore(t) + defer cleanup() + +- if err := ioutil.WriteFile(filepath.Join(td, "sha256"), []byte("was here first!"), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(td, "sha256"), []byte("was here first!"), 0644); err != nil { + t.Fatal(err) + } + +@@ -76,7 +75,7 @@ func TestStartTransactionFailure(t *testing.T) { + fms, td, cleanup := newFileMetadataStore(t) + defer cleanup() + +- if err := ioutil.WriteFile(filepath.Join(td, "tmp"), []byte("was here first!"), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(td, "tmp"), []byte("was here first!"), 0644); err != nil { + t.Fatal(err) + } + +@@ -124,7 +123,7 @@ func TestGetOrphan(t *testing.T) { + t.Fatal(err) + } + layerPath := fms.getLayerDirectory(layerid) +- if err := ioutil.WriteFile(filepath.Join(layerPath, "cache-id"), []byte(stringid.GenerateRandomID()), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(layerPath, "cache-id"), []byte(stringid.GenerateRandomID()), 0644); err != nil { + t.Fatal(err) + } + +diff --git a/layer/filestore_windows.go b/layer/filestore_windows.go +index cecad426c8..325d68b63c 100644 +--- a/layer/filestore_windows.go ++++ b/layer/filestore_windows.go +@@ -2,7 +2,6 @@ package layer // import "github.com/docker/docker/layer" + + import ( + "fmt" +- "io/ioutil" + "os" + "strings" + ) +@@ -17,7 +16,7 @@ func (fm *fileMetadataTransaction) setOS(os string) error { + + // getOS reads the "os" file from the layer filestore + func (fms *fileMetadataStore) getOS(layer ChainID) (string, error) { +- contentBytes, err := ioutil.ReadFile(fms.getLayerFilename(layer, "os")) ++ contentBytes, err := os.ReadFile(fms.getLayerFilename(layer, "os")) + if err != nil { + // For backwards compatibility, the os file may not exist. Default to "windows" if missing. + if os.IsNotExist(err) { +diff --git a/layer/layer_store.go b/layer/layer_store.go +index c58f501982..5520899b8d 100644 +--- a/layer/layer_store.go ++++ b/layer/layer_store.go +@@ -4,7 +4,6 @@ import ( + "errors" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "sync" +@@ -266,7 +265,7 @@ func (ls *layerStore) applyTar(tx *fileMetadataTransaction, ts io.Reader, parent + // discard trailing data but ensure metadata is picked up to reconstruct stream + // unconditionally call io.Copy here before checking err to ensure the resources + // allocated by NewInputTarStream above are always released +- io.Copy(ioutil.Discard, rdr) // ignore error as reader may be closed ++ io.Copy(io.Discard, rdr) // ignore error as reader may be closed + if err != nil { + return err + } +diff --git a/layer/layer_test.go b/layer/layer_test.go +index 9199b9c2db..4a4bcfb90e 100644 +--- a/layer/layer_test.go ++++ b/layer/layer_test.go +@@ -3,7 +3,6 @@ package layer // import "github.com/docker/docker/layer" + import ( + "bytes" + "io" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -47,7 +46,7 @@ func newVFSGraphDriver(td string) (graphdriver.Driver, error) { + } + + func newTestGraphDriver(t *testing.T) (graphdriver.Driver, func()) { +- td, err := ioutil.TempDir("", "graph-") ++ td, err := os.MkdirTemp("", "graph-") + if err != nil { + t.Fatal(err) + } +@@ -63,7 +62,7 @@ func newTestGraphDriver(t *testing.T) (graphdriver.Driver, func()) { + } + + func newTestStore(t *testing.T) (Store, string, func()) { +- td, err := ioutil.TempDir("", "layerstore-") ++ td, err := os.MkdirTemp("", "layerstore-") + if err != nil { + t.Fatal(err) + } +@@ -555,7 +554,7 @@ func assertLayerDiff(t *testing.T, expected []byte, layer Layer) { + } + defer ts.Close() + +- actual, err := ioutil.ReadAll(ts) ++ actual, err := io.ReadAll(ts) + if err != nil { + t.Fatal(err) + } +@@ -603,7 +602,7 @@ func byteDiff(b1, b2 []byte) ([]byte, []byte) { + } + + func tarFromFiles(files ...FileApplier) ([]byte, error) { +- td, err := ioutil.TempDir("", "tar-") ++ td, err := os.MkdirTemp("", "tar-") + if err != nil { + return nil, err + } +@@ -754,7 +753,7 @@ func TestTarStreamVerification(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- _, err = io.Copy(ioutil.Discard, ts) ++ _, err = io.Copy(io.Discard, ts) + if err == nil { + t.Fatal("expected data verification to fail") + } +diff --git a/layer/migration_test.go b/layer/migration_test.go +index 2b5c3301f8..374d8cdcdc 100644 +--- a/layer/migration_test.go ++++ b/layer/migration_test.go +@@ -4,7 +4,6 @@ import ( + "bytes" + "compress/gzip" + "io" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -33,7 +32,7 @@ func writeTarSplitFile(name string, tarContent []byte) error { + return err + } + +- if _, err := io.Copy(ioutil.Discard, rdr); err != nil { ++ if _, err := io.Copy(io.Discard, rdr); err != nil { + return err + } + +@@ -45,7 +44,7 @@ func TestLayerMigration(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Failing on Windows") + } +- td, err := ioutil.TempDir("", "migration-test-") ++ td, err := os.MkdirTemp("", "migration-test-") + if err != nil { + t.Fatal(err) + } +@@ -173,7 +172,7 @@ func tarFromFilesInGraph(graph graphdriver.Driver, graphID, parentID string, fil + } + defer ar.Close() + +- return ioutil.ReadAll(ar) ++ return io.ReadAll(ar) + } + + func TestLayerMigrationNoTarsplit(t *testing.T) { +@@ -181,7 +180,7 @@ func TestLayerMigrationNoTarsplit(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Failing on Windows") + } +- td, err := ioutil.TempDir("", "migration-test-") ++ td, err := os.MkdirTemp("", "migration-test-") + if err != nil { + t.Fatal(err) + } +diff --git a/layer/mount_test.go b/layer/mount_test.go +index 3c868b2b20..20de6e0c7c 100644 +--- a/layer/mount_test.go ++++ b/layer/mount_test.go +@@ -1,7 +1,7 @@ + package layer // import "github.com/docker/docker/layer" + + import ( +- "io/ioutil" ++ "io" + "runtime" + "sort" + "testing" +@@ -56,7 +56,7 @@ func TestMountInit(t *testing.T) { + } + defer f.Close() + +- b, err := ioutil.ReadAll(f) ++ b, err := io.ReadAll(f) + if err != nil { + t.Fatal(err) + } +@@ -254,7 +254,7 @@ func TestMountApply(t *testing.T) { + } + defer f.Close() + +- b, err := ioutil.ReadAll(f) ++ b, err := io.ReadAll(f) + if err != nil { + t.Fatal(err) + } +diff --git a/libcontainerd/local/local_windows.go b/libcontainerd/local/local_windows.go +index 85e1d8c772..ffdd12429a 100644 +--- a/libcontainerd/local/local_windows.go ++++ b/libcontainerd/local/local_windows.go +@@ -7,7 +7,7 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "os" + "path" + "path/filepath" +@@ -777,10 +777,10 @@ func newIOFromProcess(newProcess hcsshim.Process, terminal bool) (*cio.DirectIO, + + // Convert io.ReadClosers to io.Readers + if stdout != nil { +- dio.Stdout = ioutil.NopCloser(&autoClosingReader{ReadCloser: stdout}) ++ dio.Stdout = io.NopCloser(&autoClosingReader{ReadCloser: stdout}) + } + if stderr != nil { +- dio.Stderr = ioutil.NopCloser(&autoClosingReader{ReadCloser: stderr}) ++ dio.Stderr = io.NopCloser(&autoClosingReader{ReadCloser: stderr}) + } + return dio, nil + } +diff --git a/libcontainerd/supervisor/remote_daemon.go b/libcontainerd/supervisor/remote_daemon.go +index 3538612246..569941b6a9 100644 +--- a/libcontainerd/supervisor/remote_daemon.go ++++ b/libcontainerd/supervisor/remote_daemon.go +@@ -4,7 +4,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -219,7 +218,7 @@ func (r *remote) startContainerd() error { + + r.daemonPid = cmd.Process.Pid + +- err = ioutil.WriteFile(filepath.Join(r.stateDir, pidFile), []byte(fmt.Sprintf("%d", r.daemonPid)), 0660) ++ err = os.WriteFile(filepath.Join(r.stateDir, pidFile), []byte(fmt.Sprintf("%d", r.daemonPid)), 0660) + if err != nil { + system.KillProcess(r.daemonPid) + return errors.Wrap(err, "libcontainerd: failed to save daemon pid to disk") +diff --git a/oci/seccomp_test.go b/oci/seccomp_test.go +index 2efbd1c3e0..814cdaa7c0 100644 +--- a/oci/seccomp_test.go ++++ b/oci/seccomp_test.go +@@ -5,7 +5,7 @@ package oci + + import ( + "encoding/json" +- "io/ioutil" ++ "os" + "testing" + + "github.com/docker/docker/profiles/seccomp" +@@ -16,7 +16,7 @@ func TestSeccompLoadProfile(t *testing.T) { + + for _, p := range profiles { + t.Run(p, func(t *testing.T) { +- f, err := ioutil.ReadFile("fixtures/" + p) ++ f, err := os.ReadFile("fixtures/" + p) + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go +index 50b83c62c6..2c18d8b03f 100644 +--- a/pkg/archive/archive.go ++++ b/pkg/archive/archive.go +@@ -9,7 +9,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -1272,7 +1271,7 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) { + // of that file as an archive. The archive can only be read once - as soon as reading completes, + // the file will be deleted. + func NewTempArchive(src io.Reader, dir string) (*TempArchive, error) { +- f, err := ioutil.TempFile(dir, "") ++ f, err := os.CreateTemp(dir, "") + if err != nil { + return nil, err + } +diff --git a/pkg/archive/archive_linux_test.go b/pkg/archive/archive_linux_test.go +index 800fda61eb..e88e556d58 100644 +--- a/pkg/archive/archive_linux_test.go ++++ b/pkg/archive/archive_linux_test.go +@@ -1,7 +1,6 @@ + package archive // import "github.com/docker/docker/pkg/archive" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "syscall" +@@ -33,7 +32,7 @@ func setupOverlayTestDir(t *testing.T, src string) { + err = system.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0) + assert.NilError(t, err) + +- err = ioutil.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600) ++ err = os.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600) + assert.NilError(t, err) + + // Create another opaque directory containing single file but with permission 0750 +@@ -43,7 +42,7 @@ func setupOverlayTestDir(t *testing.T, src string) { + err = system.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0) + assert.NilError(t, err) + +- err = ioutil.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660) ++ err = os.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660) + assert.NilError(t, err) + + // Create regular directory with deleted file +@@ -91,13 +90,13 @@ func TestOverlayTarUntar(t *testing.T) { + assert.NilError(t, err) + defer system.Umask(oldmask) + +- src, err := ioutil.TempDir("", "docker-test-overlay-tar-src") ++ src, err := os.MkdirTemp("", "docker-test-overlay-tar-src") + assert.NilError(t, err) + defer os.RemoveAll(src) + + setupOverlayTestDir(t, src) + +- dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst") ++ dst, err := os.MkdirTemp("", "docker-test-overlay-tar-dst") + assert.NilError(t, err) + defer os.RemoveAll(dst) + +@@ -130,13 +129,13 @@ func TestOverlayTarAUFSUntar(t *testing.T) { + assert.NilError(t, err) + defer system.Umask(oldmask) + +- src, err := ioutil.TempDir("", "docker-test-overlay-tar-src") ++ src, err := os.MkdirTemp("", "docker-test-overlay-tar-src") + assert.NilError(t, err) + defer os.RemoveAll(src) + + setupOverlayTestDir(t, src) + +- dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst") ++ dst, err := os.MkdirTemp("", "docker-test-overlay-tar-dst") + assert.NilError(t, err) + defer os.RemoveAll(dst) + +diff --git a/pkg/archive/archive_test.go b/pkg/archive/archive_test.go +index d7632e1f06..b0af57a41d 100644 +--- a/pkg/archive/archive_test.go ++++ b/pkg/archive/archive_test.go +@@ -7,7 +7,6 @@ import ( + "errors" + "fmt" + "io" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -111,7 +110,7 @@ func testDecompressStream(t *testing.T, ext, compressCommand string) io.Reader { + if err != nil { + t.Fatalf("Failed to decompress %s: %v", filename, err) + } +- if _, err = ioutil.ReadAll(r); err != nil { ++ if _, err = io.ReadAll(r); err != nil { + t.Fatalf("Failed to read the decompressed stream: %v ", err) + } + if err = r.Close(); err != nil { +@@ -220,7 +219,7 @@ func TestCmdStreamLargeStderr(t *testing.T) { + } + errCh := make(chan error, 1) + go func() { +- _, err := io.Copy(ioutil.Discard, out) ++ _, err := io.Copy(io.Discard, out) + errCh <- err + }() + select { +@@ -243,7 +242,7 @@ func TestCmdStreamBad(t *testing.T) { + if err != nil { + t.Fatalf("Failed to start command: %s", err) + } +- if output, err := ioutil.ReadAll(out); err == nil { ++ if output, err := io.ReadAll(out); err == nil { + t.Fatalf("Command should have failed") + } else if err.Error() != "exit status 1: error couldn't reverse the phase pulser\n" { + t.Fatalf("Wrong error value (%s)", err) +@@ -258,7 +257,7 @@ func TestCmdStreamGood(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- if output, err := ioutil.ReadAll(out); err != nil { ++ if output, err := io.ReadAll(out); err != nil { + t.Fatalf("Command should not have failed (err=%s)", err) + } else if s := string(output); s != "hello\n" { + t.Fatalf("Command output should be '%s', not '%s'", "hello\\n", output) +@@ -266,7 +265,7 @@ func TestCmdStreamGood(t *testing.T) { + } + + func TestUntarPathWithInvalidDest(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-archive-test") ++ tempFolder, err := os.MkdirTemp("", "docker-archive-test") + assert.NilError(t, err) + defer os.RemoveAll(tempFolder) + invalidDestFolder := filepath.Join(tempFolder, "invalidDest") +@@ -295,7 +294,7 @@ func TestUntarPathWithInvalidDest(t *testing.T) { + } + + func TestUntarPathWithInvalidSrc(t *testing.T) { +- dest, err := ioutil.TempDir("", "docker-archive-test") ++ dest, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatalf("Fail to create the destination file") + } +@@ -308,7 +307,7 @@ func TestUntarPathWithInvalidSrc(t *testing.T) { + + func TestUntarPath(t *testing.T) { + skip.If(t, runtime.GOOS != "windows" && os.Getuid() != 0, "skipping test that requires root") +- tmpFolder, err := ioutil.TempDir("", "docker-archive-test") ++ tmpFolder, err := os.MkdirTemp("", "docker-archive-test") + assert.NilError(t, err) + defer os.RemoveAll(tmpFolder) + srcFile := filepath.Join(tmpFolder, "src") +@@ -345,7 +344,7 @@ func TestUntarPath(t *testing.T) { + + // Do the same test as above but with the destination as file, it should fail + func TestUntarPathWithDestinationFile(t *testing.T) { +- tmpFolder, err := ioutil.TempDir("", "docker-archive-test") ++ tmpFolder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } +@@ -381,7 +380,7 @@ func TestUntarPathWithDestinationFile(t *testing.T) { + // and the destination file is a directory + // It's working, see https://github.com/docker/docker/issues/10040 + func TestUntarPathWithDestinationSrcFileAsFolder(t *testing.T) { +- tmpFolder, err := ioutil.TempDir("", "docker-archive-test") ++ tmpFolder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } +@@ -421,7 +420,7 @@ func TestUntarPathWithDestinationSrcFileAsFolder(t *testing.T) { + } + + func TestCopyWithTarInvalidSrc(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-archive-test") ++ tempFolder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(nil) + } +@@ -439,7 +438,7 @@ func TestCopyWithTarInvalidSrc(t *testing.T) { + + func TestCopyWithTarInexistentDestWillCreateIt(t *testing.T) { + skip.If(t, runtime.GOOS != "windows" && os.Getuid() != 0, "skipping test that requires root") +- tempFolder, err := ioutil.TempDir("", "docker-archive-test") ++ tempFolder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(nil) + } +@@ -461,7 +460,7 @@ func TestCopyWithTarInexistentDestWillCreateIt(t *testing.T) { + + // Test CopyWithTar with a file as src + func TestCopyWithTarSrcFile(t *testing.T) { +- folder, err := ioutil.TempDir("", "docker-archive-test") ++ folder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } +@@ -477,7 +476,7 @@ func TestCopyWithTarSrcFile(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- ioutil.WriteFile(src, []byte("content"), 0777) ++ os.WriteFile(src, []byte("content"), 0777) + err = defaultCopyWithTar(src, dest) + if err != nil { + t.Fatalf("archiver.CopyWithTar shouldn't throw an error, %s.", err) +@@ -491,7 +490,7 @@ func TestCopyWithTarSrcFile(t *testing.T) { + + // Test CopyWithTar with a folder as src + func TestCopyWithTarSrcFolder(t *testing.T) { +- folder, err := ioutil.TempDir("", "docker-archive-test") ++ folder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } +@@ -506,7 +505,7 @@ func TestCopyWithTarSrcFolder(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- ioutil.WriteFile(filepath.Join(src, "file"), []byte("content"), 0777) ++ os.WriteFile(filepath.Join(src, "file"), []byte("content"), 0777) + err = defaultCopyWithTar(src, dest) + if err != nil { + t.Fatalf("archiver.CopyWithTar shouldn't throw an error, %s.", err) +@@ -519,7 +518,7 @@ func TestCopyWithTarSrcFolder(t *testing.T) { + } + + func TestCopyFileWithTarInvalidSrc(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-archive-test") ++ tempFolder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } +@@ -537,7 +536,7 @@ func TestCopyFileWithTarInvalidSrc(t *testing.T) { + } + + func TestCopyFileWithTarInexistentDestWillCreateIt(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-archive-test") ++ tempFolder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(nil) + } +@@ -560,7 +559,7 @@ func TestCopyFileWithTarInexistentDestWillCreateIt(t *testing.T) { + } + + func TestCopyFileWithTarSrcFolder(t *testing.T) { +- folder, err := ioutil.TempDir("", "docker-archive-copyfilewithtar-test") ++ folder, err := os.MkdirTemp("", "docker-archive-copyfilewithtar-test") + if err != nil { + t.Fatal(err) + } +@@ -582,7 +581,7 @@ func TestCopyFileWithTarSrcFolder(t *testing.T) { + } + + func TestCopyFileWithTarSrcFile(t *testing.T) { +- folder, err := ioutil.TempDir("", "docker-archive-test") ++ folder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } +@@ -598,7 +597,7 @@ func TestCopyFileWithTarSrcFile(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- ioutil.WriteFile(src, []byte("content"), 0777) ++ os.WriteFile(src, []byte("content"), 0777) + err = defaultCopyWithTar(src, dest+"/") + if err != nil { + t.Fatalf("archiver.CopyFileWithTar shouldn't throw an error, %s.", err) +@@ -621,13 +620,13 @@ func TestTarFiles(t *testing.T) { + } + + func checkNoChanges(fileNum int, hardlinks bool) error { +- srcDir, err := ioutil.TempDir("", "docker-test-srcDir") ++ srcDir, err := os.MkdirTemp("", "docker-test-srcDir") + if err != nil { + return err + } + defer os.RemoveAll(srcDir) + +- destDir, err := ioutil.TempDir("", "docker-test-destDir") ++ destDir, err := os.MkdirTemp("", "docker-test-destDir") + if err != nil { + return err + } +@@ -672,7 +671,7 @@ func tarUntar(t *testing.T, origin string, options *TarOptions) ([]Change, error + return nil, fmt.Errorf("Wrong compression detected. Actual compression: %s, found %s", compression.Extension(), detectedCompression.Extension()) + } + +- tmp, err := ioutil.TempDir("", "docker-test-untar") ++ tmp, err := os.MkdirTemp("", "docker-test-untar") + if err != nil { + return nil, err + } +@@ -688,18 +687,18 @@ func tarUntar(t *testing.T, origin string, options *TarOptions) ([]Change, error + } + + func TestTarUntar(t *testing.T) { +- origin, err := ioutil.TempDir("", "docker-test-untar-origin") ++ origin, err := os.MkdirTemp("", "docker-test-untar-origin") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(origin) +- if err := ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700); err != nil { ++ if err := os.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700); err != nil { + t.Fatal(err) + } +- if err := ioutil.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { ++ if err := os.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { + t.Fatal(err) + } +- if err := ioutil.WriteFile(filepath.Join(origin, "3"), []byte("will be ignored"), 0700); err != nil { ++ if err := os.WriteFile(filepath.Join(origin, "3"), []byte("will be ignored"), 0700); err != nil { + t.Fatal(err) + } + +@@ -723,12 +722,12 @@ func TestTarUntar(t *testing.T) { + } + + func TestTarWithOptionsChownOptsAlwaysOverridesIdPair(t *testing.T) { +- origin, err := ioutil.TempDir("", "docker-test-tar-chown-opt") ++ origin, err := os.MkdirTemp("", "docker-test-tar-chown-opt") + assert.NilError(t, err) + + defer os.RemoveAll(origin) + filePath := filepath.Join(origin, "1") +- err = ioutil.WriteFile(filePath, []byte("hello world"), 0700) ++ err = os.WriteFile(filePath, []byte("hello world"), 0700) + assert.NilError(t, err) + + idMaps := []idtools.IDMap{ +@@ -774,18 +773,18 @@ func TestTarWithOptionsChownOptsAlwaysOverridesIdPair(t *testing.T) { + } + + func TestTarWithOptions(t *testing.T) { +- origin, err := ioutil.TempDir("", "docker-test-untar-origin") ++ origin, err := os.MkdirTemp("", "docker-test-untar-origin") + if err != nil { + t.Fatal(err) + } +- if _, err := ioutil.TempDir(origin, "folder"); err != nil { ++ if _, err := os.MkdirTemp(origin, "folder"); err != nil { + t.Fatal(err) + } + defer os.RemoveAll(origin) +- if err := ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700); err != nil { ++ if err := os.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700); err != nil { + t.Fatal(err) + } +- if err := ioutil.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { ++ if err := os.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { + t.Fatal(err) + } + +@@ -816,7 +815,7 @@ func TestTarWithOptions(t *testing.T) { + // Failing prevents the archives from being uncompressed during ADD + func TestTypeXGlobalHeaderDoesNotFail(t *testing.T) { + hdr := tar.Header{Typeflag: tar.TypeXGlobalHeader} +- tmpDir, err := ioutil.TempDir("", "docker-test-archive-pax-test") ++ tmpDir, err := os.MkdirTemp("", "docker-test-archive-pax-test") + if err != nil { + t.Fatal(err) + } +@@ -862,7 +861,7 @@ func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks + fileData := []byte("fooo") + for n := 0; n < numberOfFiles; n++ { + fileName := fmt.Sprintf("file-%d", n) +- if err := ioutil.WriteFile(filepath.Join(targetPath, fileName), fileData, 0700); err != nil { ++ if err := os.WriteFile(filepath.Join(targetPath, fileName), fileData, 0700); err != nil { + return 0, err + } + if makeLinks { +@@ -876,11 +875,11 @@ func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks + } + + func BenchmarkTarUntar(b *testing.B) { +- origin, err := ioutil.TempDir("", "docker-test-untar-origin") ++ origin, err := os.MkdirTemp("", "docker-test-untar-origin") + if err != nil { + b.Fatal(err) + } +- tempDir, err := ioutil.TempDir("", "docker-test-untar-destination") ++ tempDir, err := os.MkdirTemp("", "docker-test-untar-destination") + if err != nil { + b.Fatal(err) + } +@@ -904,11 +903,11 @@ func BenchmarkTarUntar(b *testing.B) { + } + + func BenchmarkTarUntarWithLinks(b *testing.B) { +- origin, err := ioutil.TempDir("", "docker-test-untar-origin") ++ origin, err := os.MkdirTemp("", "docker-test-untar-origin") + if err != nil { + b.Fatal(err) + } +- tempDir, err := ioutil.TempDir("", "docker-test-untar-destination") ++ tempDir, err := os.MkdirTemp("", "docker-test-untar-destination") + if err != nil { + b.Fatal(err) + } +@@ -1159,7 +1158,7 @@ func TestUntarInvalidSymlink(t *testing.T) { + } + + func TestTempArchiveCloseMultipleTimes(t *testing.T) { +- reader := ioutil.NopCloser(strings.NewReader("hello")) ++ reader := io.NopCloser(strings.NewReader("hello")) + tempArchive, err := NewTempArchive(reader, "") + assert.NilError(t, err) + buf := make([]byte, 10) +@@ -1184,7 +1183,7 @@ func TestXGlobalNoParent(t *testing.T) { + Typeflag: tar.TypeXGlobalHeader, + }) + assert.NilError(t, err) +- tmpDir, err := ioutil.TempDir("", "pax-test") ++ tmpDir, err := os.MkdirTemp("", "pax-test") + assert.NilError(t, err) + defer os.RemoveAll(tmpDir) + err = Untar(buf, tmpDir, nil) +@@ -1255,7 +1254,7 @@ func TestPrefixHeaderReadable(t *testing.T) { + // https://gist.github.com/stevvooe/e2a790ad4e97425896206c0816e1a882#file-out-go + var testFile = []byte("\x1f\x8b\x08\x08\x44\x21\x68\x59\x00\x03\x74\x2e\x74\x61\x72\x00\x4b\xcb\xcf\x67\xa0\x35\x30\x80\x00\x86\x06\x10\x47\x01\xc1\x37\x40\x00\x54\xb6\xb1\xa1\xa9\x99\x09\x48\x25\x1d\x40\x69\x71\x49\x62\x91\x02\xe5\x76\xa1\x79\x84\x21\x91\xd6\x80\x72\xaf\x8f\x82\x51\x30\x0a\x46\x36\x00\x00\xf0\x1c\x1e\x95\x00\x06\x00\x00") + +- tmpDir, err := ioutil.TempDir("", "prefix-test") ++ tmpDir, err := os.MkdirTemp("", "prefix-test") + assert.NilError(t, err) + defer os.RemoveAll(tmpDir) + err = Untar(bytes.NewReader(testFile), tmpDir, nil) +@@ -1269,7 +1268,7 @@ func TestPrefixHeaderReadable(t *testing.T) { + } + + func buildSourceArchive(t *testing.T, numberOfFiles int) (io.ReadCloser, func()) { +- srcDir, err := ioutil.TempDir("", "docker-test-srcDir") ++ srcDir, err := os.MkdirTemp("", "docker-test-srcDir") + assert.NilError(t, err) + + _, err = prepareUntarSourceDirectory(numberOfFiles, srcDir, false) +@@ -1310,17 +1309,17 @@ func appendModifier(path string, header *tar.Header, content io.Reader) (*tar.He + + func readFileFromArchive(t *testing.T, archive io.ReadCloser, name string, expectedCount int, doc string) string { + skip.If(t, runtime.GOOS != "windows" && os.Getuid() != 0, "skipping test that requires root") +- destDir, err := ioutil.TempDir("", "docker-test-destDir") ++ destDir, err := os.MkdirTemp("", "docker-test-destDir") + assert.NilError(t, err) + defer os.RemoveAll(destDir) + + err = Untar(archive, destDir, nil) + assert.NilError(t, err) + +- files, _ := ioutil.ReadDir(destDir) ++ files, _ := os.ReadDir(destDir) + assert.Check(t, is.Len(files, expectedCount), doc) + +- content, err := ioutil.ReadFile(filepath.Join(destDir, name)) ++ content, err := os.ReadFile(filepath.Join(destDir, name)) + assert.Check(t, err) + return string(content) + } +diff --git a/pkg/archive/archive_unix_test.go b/pkg/archive/archive_unix_test.go +index 194768387c..3c8ca7fea3 100644 +--- a/pkg/archive/archive_unix_test.go ++++ b/pkg/archive/archive_unix_test.go +@@ -7,7 +7,7 @@ import ( + "archive/tar" + "bytes" + "fmt" +- "io/ioutil" ++ "io" + "os" + "os/exec" + "path/filepath" +@@ -72,11 +72,11 @@ func TestChmodTarEntry(t *testing.T) { + } + + func TestTarWithHardLink(t *testing.T) { +- origin, err := ioutil.TempDir("", "docker-test-tar-hardlink") ++ origin, err := os.MkdirTemp("", "docker-test-tar-hardlink") + assert.NilError(t, err) + defer os.RemoveAll(origin) + +- err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) ++ err = os.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) + assert.NilError(t, err) + + err = os.Link(filepath.Join(origin, "1"), filepath.Join(origin, "2")) +@@ -91,7 +91,7 @@ func TestTarWithHardLink(t *testing.T) { + t.Skipf("skipping since hardlinks don't work here; expected 2 links, got %d", i1) + } + +- dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest") ++ dest, err := os.MkdirTemp("", "docker-test-tar-hardlink-dest") + assert.NilError(t, err) + defer os.RemoveAll(dest) + +@@ -100,7 +100,7 @@ func TestTarWithHardLink(t *testing.T) { + assert.NilError(t, err) + + // ensure we can read the whole thing with no error, before writing back out +- buf, err := ioutil.ReadAll(fh) ++ buf, err := io.ReadAll(fh) + assert.NilError(t, err) + + bRdr := bytes.NewReader(buf) +@@ -117,7 +117,7 @@ func TestTarWithHardLink(t *testing.T) { + } + + func TestTarWithHardLinkAndRebase(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "docker-test-tar-hardlink-rebase") ++ tmpDir, err := os.MkdirTemp("", "docker-test-tar-hardlink-rebase") + assert.NilError(t, err) + defer os.RemoveAll(tmpDir) + +@@ -125,7 +125,7 @@ func TestTarWithHardLinkAndRebase(t *testing.T) { + err = os.Mkdir(origin, 0700) + assert.NilError(t, err) + +- err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) ++ err = os.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) + assert.NilError(t, err) + + err = os.Link(filepath.Join(origin, "1"), filepath.Join(origin, "2")) +@@ -166,7 +166,7 @@ func TestUntarParentPathPermissions(t *testing.T) { + w := tar.NewWriter(buf) + err := w.WriteHeader(&tar.Header{Name: "foo/bar"}) + assert.NilError(t, err) +- tmpDir, err := ioutil.TempDir("", t.Name()) ++ tmpDir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(tmpDir) + err = Untar(buf, tmpDir, nil) +@@ -206,11 +206,11 @@ func getInode(path string) (uint64, error) { + func TestTarWithBlockCharFifo(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") + skip.If(t, sys.RunningInUserNS(), "skipping test that requires initial userns") +- origin, err := ioutil.TempDir("", "docker-test-tar-hardlink") ++ origin, err := os.MkdirTemp("", "docker-test-tar-hardlink") + assert.NilError(t, err) + + defer os.RemoveAll(origin) +- err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) ++ err = os.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) + assert.NilError(t, err) + + err = system.Mknod(filepath.Join(origin, "2"), unix.S_IFBLK, int(system.Mkdev(int64(12), int64(5)))) +@@ -220,7 +220,7 @@ func TestTarWithBlockCharFifo(t *testing.T) { + err = system.Mknod(filepath.Join(origin, "4"), unix.S_IFIFO, int(system.Mkdev(int64(12), int64(5)))) + assert.NilError(t, err) + +- dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest") ++ dest, err := os.MkdirTemp("", "docker-test-tar-hardlink-dest") + assert.NilError(t, err) + defer os.RemoveAll(dest) + +@@ -229,7 +229,7 @@ func TestTarWithBlockCharFifo(t *testing.T) { + assert.NilError(t, err) + + // ensure we can read the whole thing with no error, before writing back out +- buf, err := ioutil.ReadAll(fh) ++ buf, err := io.ReadAll(fh) + assert.NilError(t, err) + + bRdr := bytes.NewReader(buf) +@@ -254,15 +254,15 @@ func TestTarUntarWithXattr(t *testing.T) { + t.Skip("getcap not installed") + } + +- origin, err := ioutil.TempDir("", "docker-test-untar-origin") ++ origin, err := os.MkdirTemp("", "docker-test-untar-origin") + assert.NilError(t, err) + defer os.RemoveAll(origin) +- err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) ++ err = os.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) + assert.NilError(t, err) + +- err = ioutil.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700) ++ err = os.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700) + assert.NilError(t, err) +- err = ioutil.WriteFile(filepath.Join(origin, "3"), []byte("will be ignored"), 0700) ++ err = os.WriteFile(filepath.Join(origin, "3"), []byte("will be ignored"), 0700) + assert.NilError(t, err) + // there is no known Go implementation of setcap/getcap with support for v3 file capability + out, err := exec.Command("setcap", "cap_block_suspend+ep", filepath.Join(origin, "2")).CombinedOutput() +diff --git a/pkg/archive/archive_windows_test.go b/pkg/archive/archive_windows_test.go +index c263290b0f..f03b1e2d82 100644 +--- a/pkg/archive/archive_windows_test.go ++++ b/pkg/archive/archive_windows_test.go +@@ -4,7 +4,6 @@ + package archive // import "github.com/docker/docker/pkg/archive" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -15,7 +14,7 @@ func TestCopyFileWithInvalidDest(t *testing.T) { + // recently changed in CopyWithTar as used to pass. Further investigation + // is required. + t.Skip("Currently fails") +- folder, err := ioutil.TempDir("", "docker-archive-test") ++ folder, err := os.MkdirTemp("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } +@@ -27,7 +26,7 @@ func TestCopyFileWithInvalidDest(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- ioutil.WriteFile(src, []byte("content"), 0777) ++ os.WriteFile(src, []byte("content"), 0777) + err = defaultCopyWithTar(src, dest) + if err == nil { + t.Fatalf("archiver.CopyWithTar should throw an error on invalid dest.") +diff --git a/pkg/archive/changes.go b/pkg/archive/changes.go +index aedb91b035..a0f25942c1 100644 +--- a/pkg/archive/changes.go ++++ b/pkg/archive/changes.go +@@ -5,7 +5,6 @@ import ( + "bytes" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "sort" +@@ -348,7 +347,7 @@ func ChangesDirs(newDir, oldDir string) ([]Change, error) { + oldRoot, newRoot *FileInfo + ) + if oldDir == "" { +- emptyDir, err := ioutil.TempDir("", "empty") ++ emptyDir, err := os.MkdirTemp("", "empty") + if err != nil { + return nil, err + } +diff --git a/pkg/archive/changes_posix_test.go b/pkg/archive/changes_posix_test.go +index 019a0250f3..4c71cb2575 100644 +--- a/pkg/archive/changes_posix_test.go ++++ b/pkg/archive/changes_posix_test.go +@@ -4,7 +4,6 @@ import ( + "archive/tar" + "fmt" + "io" +- "io/ioutil" + "os" + "path" + "sort" +@@ -16,7 +15,7 @@ func TestHardLinkOrder(t *testing.T) { + msg := []byte("Hey y'all") + + // Create dir +- src, err := ioutil.TempDir("", "docker-hardlink-test-src-") ++ src, err := os.MkdirTemp("", "docker-hardlink-test-src-") + if err != nil { + t.Fatal(err) + } +@@ -34,7 +33,7 @@ func TestHardLinkOrder(t *testing.T) { + }() + } + // Create dest, with changes that includes hardlinks +- dest, err := ioutil.TempDir("", "docker-hardlink-test-dest-") ++ dest, err := os.MkdirTemp("", "docker-hardlink-test-dest-") + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/archive/changes_test.go b/pkg/archive/changes_test.go +index 0a2689d7aa..dfecdbb54e 100644 +--- a/pkg/archive/changes_test.go ++++ b/pkg/archive/changes_test.go +@@ -1,7 +1,6 @@ + package archive // import "github.com/docker/docker/pkg/archive" + + import ( +- "io/ioutil" + "os" + "os/exec" + "path" +@@ -98,7 +97,7 @@ func provisionSampleDir(t *testing.T, root string, files []FileData) { + err := os.MkdirAll(p, info.permissions) + assert.NilError(t, err) + } else if info.filetype == Regular { +- err := ioutil.WriteFile(p, []byte(info.contents), info.permissions) ++ err := os.WriteFile(p, []byte(info.contents), info.permissions) + assert.NilError(t, err) + } else if info.filetype == Symlink { + err := os.Symlink(info.contents, p) +@@ -132,10 +131,10 @@ func TestChangeString(t *testing.T) { + } + + func TestChangesWithNoChanges(t *testing.T) { +- rwLayer, err := ioutil.TempDir("", "docker-changes-test") ++ rwLayer, err := os.MkdirTemp("", "docker-changes-test") + assert.NilError(t, err) + defer os.RemoveAll(rwLayer) +- layer, err := ioutil.TempDir("", "docker-changes-test-layer") ++ layer, err := os.MkdirTemp("", "docker-changes-test-layer") + assert.NilError(t, err) + defer os.RemoveAll(layer) + createSampleDir(t, layer) +@@ -148,14 +147,14 @@ func TestChangesWithNoChanges(t *testing.T) { + + func TestChangesWithChanges(t *testing.T) { + // Mock the readonly layer +- layer, err := ioutil.TempDir("", "docker-changes-test-layer") ++ layer, err := os.MkdirTemp("", "docker-changes-test-layer") + assert.NilError(t, err) + defer os.RemoveAll(layer) + createSampleDir(t, layer) + os.MkdirAll(path.Join(layer, "dir1/subfolder"), 0740) + + // Mock the RW layer +- rwLayer, err := ioutil.TempDir("", "docker-changes-test") ++ rwLayer, err := os.MkdirTemp("", "docker-changes-test") + assert.NilError(t, err) + defer os.RemoveAll(rwLayer) + +@@ -163,14 +162,14 @@ func TestChangesWithChanges(t *testing.T) { + dir1 := path.Join(rwLayer, "dir1") + os.MkdirAll(dir1, 0740) + deletedFile := path.Join(dir1, ".wh.file1-2") +- ioutil.WriteFile(deletedFile, []byte{}, 0600) ++ os.WriteFile(deletedFile, []byte{}, 0600) + modifiedFile := path.Join(dir1, "file1-1") +- ioutil.WriteFile(modifiedFile, []byte{0x00}, 01444) ++ os.WriteFile(modifiedFile, []byte{0x00}, 01444) + // Let's add a subfolder for a newFile + subfolder := path.Join(dir1, "subfolder") + os.MkdirAll(subfolder, 0740) + newFile := path.Join(subfolder, "newFile") +- ioutil.WriteFile(newFile, []byte{}, 0740) ++ os.WriteFile(newFile, []byte{}, 0740) + + changes, err := Changes([]string{layer}, rwLayer) + assert.NilError(t, err) +@@ -191,7 +190,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("needs more investigation") + } +- baseLayer, err := ioutil.TempDir("", "docker-changes-test.") ++ baseLayer, err := os.MkdirTemp("", "docker-changes-test.") + assert.NilError(t, err) + defer os.RemoveAll(baseLayer) + +@@ -199,9 +198,9 @@ func TestChangesWithChangesGH13590(t *testing.T) { + os.MkdirAll(dir3, 07400) + + file := path.Join(dir3, "file.txt") +- ioutil.WriteFile(file, []byte("hello"), 0666) ++ os.WriteFile(file, []byte("hello"), 0666) + +- layer, err := ioutil.TempDir("", "docker-changes-test2.") ++ layer, err := os.MkdirTemp("", "docker-changes-test2.") + assert.NilError(t, err) + defer os.RemoveAll(layer) + +@@ -212,7 +211,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { + + os.Remove(path.Join(layer, "dir1/dir2/dir3/file.txt")) + file = path.Join(layer, "dir1/dir2/dir3/file1.txt") +- ioutil.WriteFile(file, []byte("bye"), 0666) ++ os.WriteFile(file, []byte("bye"), 0666) + + changes, err := Changes([]string{baseLayer}, layer) + assert.NilError(t, err) +@@ -224,7 +223,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { + checkChanges(expectedChanges, changes, t) + + // Now test changing a file +- layer, err = ioutil.TempDir("", "docker-changes-test3.") ++ layer, err = os.MkdirTemp("", "docker-changes-test3.") + assert.NilError(t, err) + defer os.RemoveAll(layer) + +@@ -233,7 +232,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { + } + + file = path.Join(layer, "dir1/dir2/dir3/file.txt") +- ioutil.WriteFile(file, []byte("bye"), 0666) ++ os.WriteFile(file, []byte("bye"), 0666) + + changes, err = Changes([]string{baseLayer}, layer) + assert.NilError(t, err) +@@ -246,7 +245,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { + + // Create a directory, copy it, make sure we report no changes between the two + func TestChangesDirsEmpty(t *testing.T) { +- src, err := ioutil.TempDir("", "docker-changes-test") ++ src, err := os.MkdirTemp("", "docker-changes-test") + assert.NilError(t, err) + defer os.RemoveAll(src) + createSampleDir(t, src) +@@ -278,13 +277,13 @@ func mutateSampleDir(t *testing.T, root string) { + assert.NilError(t, err) + + // Rewrite a file +- err = ioutil.WriteFile(path.Join(root, "file2"), []byte("fileNN\n"), 0777) ++ err = os.WriteFile(path.Join(root, "file2"), []byte("fileNN\n"), 0777) + assert.NilError(t, err) + + // Replace a file + err = os.RemoveAll(path.Join(root, "file3")) + assert.NilError(t, err) +- err = ioutil.WriteFile(path.Join(root, "file3"), []byte("fileMM\n"), 0404) ++ err = os.WriteFile(path.Join(root, "file3"), []byte("fileMM\n"), 0404) + assert.NilError(t, err) + + // Touch file +@@ -298,7 +297,7 @@ func mutateSampleDir(t *testing.T, root string) { + assert.NilError(t, err) + + // Create new file +- err = ioutil.WriteFile(path.Join(root, "filenew"), []byte("filenew\n"), 0777) ++ err = os.WriteFile(path.Join(root, "filenew"), []byte("filenew\n"), 0777) + assert.NilError(t, err) + + // Create new dir +@@ -319,7 +318,7 @@ func mutateSampleDir(t *testing.T, root string) { + // Replace dir with file + err = os.RemoveAll(path.Join(root, "dir2")) + assert.NilError(t, err) +- err = ioutil.WriteFile(path.Join(root, "dir2"), []byte("dir2\n"), 0777) ++ err = os.WriteFile(path.Join(root, "dir2"), []byte("dir2\n"), 0777) + assert.NilError(t, err) + + // Touch dir +@@ -328,7 +327,7 @@ func mutateSampleDir(t *testing.T, root string) { + } + + func TestChangesDirsMutated(t *testing.T) { +- src, err := ioutil.TempDir("", "docker-changes-test") ++ src, err := os.MkdirTemp("", "docker-changes-test") + assert.NilError(t, err) + createSampleDir(t, src) + dst := src + "-copy" +@@ -404,7 +403,7 @@ func TestApplyLayer(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("needs further investigation") + } +- src, err := ioutil.TempDir("", "docker-changes-test") ++ src, err := os.MkdirTemp("", "docker-changes-test") + assert.NilError(t, err) + createSampleDir(t, src) + defer os.RemoveAll(src) +@@ -440,11 +439,11 @@ func TestChangesSizeWithHardlinks(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("needs further investigation") + } +- srcDir, err := ioutil.TempDir("", "docker-test-srcDir") ++ srcDir, err := os.MkdirTemp("", "docker-test-srcDir") + assert.NilError(t, err) + defer os.RemoveAll(srcDir) + +- destDir, err := ioutil.TempDir("", "docker-test-destDir") ++ destDir, err := os.MkdirTemp("", "docker-test-destDir") + assert.NilError(t, err) + defer os.RemoveAll(destDir) + +@@ -478,14 +477,14 @@ func TestChangesSizeWithOnlyDeleteChanges(t *testing.T) { + } + + func TestChangesSize(t *testing.T) { +- parentPath, err := ioutil.TempDir("", "docker-changes-test") ++ parentPath, err := os.MkdirTemp("", "docker-changes-test") + assert.NilError(t, err) + defer os.RemoveAll(parentPath) + addition := path.Join(parentPath, "addition") +- err = ioutil.WriteFile(addition, []byte{0x01, 0x01, 0x01}, 0744) ++ err = os.WriteFile(addition, []byte{0x01, 0x01, 0x01}, 0744) + assert.NilError(t, err) + modification := path.Join(parentPath, "modification") +- err = ioutil.WriteFile(modification, []byte{0x01, 0x01, 0x01}, 0744) ++ err = os.WriteFile(modification, []byte{0x01, 0x01, 0x01}, 0744) + assert.NilError(t, err) + + changes := []Change{ +diff --git a/pkg/archive/copy.go b/pkg/archive/copy.go +index 4b9f504d7d..b9be0d5ec8 100644 +--- a/pkg/archive/copy.go ++++ b/pkg/archive/copy.go +@@ -4,7 +4,6 @@ import ( + "archive/tar" + "errors" + "io" +- "io/ioutil" + "os" + "path/filepath" + "strings" +@@ -261,7 +260,7 @@ func PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo CopyInfo) (dstDir + // The destination exists as a directory. No alteration + // to srcContent is needed as its contents can be + // simply extracted to the destination directory. +- return dstInfo.Path, ioutil.NopCloser(srcContent), nil ++ return dstInfo.Path, io.NopCloser(srcContent), nil + case dstInfo.Exists && srcInfo.IsDir: + // The destination exists as some type of file and the source + // content is a directory. This is an error condition since +diff --git a/pkg/archive/copy_unix_test.go b/pkg/archive/copy_unix_test.go +index 7c32062619..efb20e225d 100644 +--- a/pkg/archive/copy_unix_test.go ++++ b/pkg/archive/copy_unix_test.go +@@ -11,7 +11,6 @@ import ( + "encoding/hex" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "strings" +@@ -29,10 +28,10 @@ func removeAllPaths(paths ...string) { + func getTestTempDirs(t *testing.T) (tmpDirA, tmpDirB string) { + var err error + +- tmpDirA, err = ioutil.TempDir("", "archive-copy-test") ++ tmpDirA, err = os.MkdirTemp("", "archive-copy-test") + assert.NilError(t, err) + +- tmpDirB, err = ioutil.TempDir("", "archive-copy-test") ++ tmpDirB, err = os.MkdirTemp("", "archive-copy-test") + assert.NilError(t, err) + + return +diff --git a/pkg/archive/diff.go b/pkg/archive/diff.go +index 27897e6ab7..e095104bd9 100644 +--- a/pkg/archive/diff.go ++++ b/pkg/archive/diff.go +@@ -4,7 +4,6 @@ import ( + "archive/tar" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -100,7 +99,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, + basename := filepath.Base(hdr.Name) + aufsHardlinks[basename] = hdr + if aufsTempdir == "" { +- if aufsTempdir, err = ioutil.TempDir("", "dockerplnk"); err != nil { ++ if aufsTempdir, err = os.MkdirTemp("", "dockerplnk"); err != nil { + return 0, err + } + defer os.RemoveAll(aufsTempdir) +diff --git a/pkg/archive/diff_test.go b/pkg/archive/diff_test.go +index 1d3f166127..aac7b7c340 100644 +--- a/pkg/archive/diff_test.go ++++ b/pkg/archive/diff_test.go +@@ -3,7 +3,6 @@ package archive // import "github.com/docker/docker/pkg/archive" + import ( + "archive/tar" + "io" +- "io/ioutil" + "os" + "path/filepath" + "reflect" +@@ -197,7 +196,7 @@ func TestApplyLayerInvalidSymlink(t *testing.T) { + } + + func TestApplyLayerWhiteouts(t *testing.T) { +- wd, err := ioutil.TempDir("", "graphdriver-test-whiteouts") ++ wd, err := os.MkdirTemp("", "graphdriver-test-whiteouts") + if err != nil { + return + } +@@ -313,7 +312,7 @@ func TestApplyLayerWhiteouts(t *testing.T) { + } + + func makeTestLayer(paths []string) (rc io.ReadCloser, err error) { +- tmpDir, err := ioutil.TempDir("", "graphdriver-test-mklayer") ++ tmpDir, err := os.MkdirTemp("", "graphdriver-test-mklayer") + if err != nil { + return + } +@@ -330,7 +329,7 @@ func makeTestLayer(paths []string) (rc io.ReadCloser, err error) { + return + } + } else { +- if err = ioutil.WriteFile(filepath.Join(tmpDir, p), nil, 0600); err != nil { ++ if err = os.WriteFile(filepath.Join(tmpDir, p), nil, 0600); err != nil { + return + } + } +diff --git a/pkg/archive/example_changes.go b/pkg/archive/example_changes.go +index 48f270aaf8..36cb6c3cb5 100644 +--- a/pkg/archive/example_changes.go ++++ b/pkg/archive/example_changes.go +@@ -10,7 +10,6 @@ import ( + "flag" + "fmt" + "io" +- "io/ioutil" + "os" + "path" + +@@ -40,7 +39,7 @@ func main() { + + if len(*flNewDir) == 0 { + var err error +- newDir, err = ioutil.TempDir("", "docker-test-newDir") ++ newDir, err = os.MkdirTemp("", "docker-test-newDir") + if err != nil { + log.Fatal(err) + } +@@ -53,7 +52,7 @@ func main() { + } + + if len(*flOldDir) == 0 { +- oldDir, err := ioutil.TempDir("", "docker-test-oldDir") ++ oldDir, err := os.MkdirTemp("", "docker-test-oldDir") + if err != nil { + log.Fatal(err) + } +@@ -84,7 +83,7 @@ func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks + fileData := []byte("fooo") + for n := 0; n < numberOfFiles; n++ { + fileName := fmt.Sprintf("file-%d", n) +- if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil { ++ if err := os.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil { + return 0, err + } + if makeLinks { +diff --git a/pkg/archive/utils_test.go b/pkg/archive/utils_test.go +index a20f58ddab..a00ae680c0 100644 +--- a/pkg/archive/utils_test.go ++++ b/pkg/archive/utils_test.go +@@ -5,7 +5,6 @@ import ( + "bytes" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "time" +@@ -34,7 +33,7 @@ var testUntarFns = map[string]func(string, io.Reader) error{ + // + // When using testBreakout make sure you cover one of the scenarios listed above. + func testBreakout(untarFn string, tmpdir string, headers []*tar.Header) error { +- tmpdir, err := ioutil.TempDir("", tmpdir) ++ tmpdir, err := os.MkdirTemp("", tmpdir) + if err != nil { + return err + } +@@ -54,7 +53,7 @@ func testBreakout(untarFn string, tmpdir string, headers []*tar.Header) error { + if err != nil { + return err + } +- if err := ioutil.WriteFile(hello, helloData, 0644); err != nil { ++ if err := os.WriteFile(hello, helloData, 0644); err != nil { + return err + } + helloStat, err := os.Stat(hello) +@@ -119,7 +118,7 @@ func testBreakout(untarFn string, tmpdir string, headers []*tar.Header) error { + return fmt.Errorf("archive breakout: could not lstat %q: %v", hello, err) + } + defer f.Close() +- b, err := ioutil.ReadAll(f) ++ b, err := io.ReadAll(f) + if err != nil { + return err + } +@@ -153,7 +152,7 @@ func testBreakout(untarFn string, tmpdir string, headers []*tar.Header) error { + // skip file if error + return nil + } +- b, err := ioutil.ReadFile(path) ++ b, err := os.ReadFile(path) + if err != nil { + // Houston, we have a problem. Aborting (space)walk. + return err +diff --git a/pkg/authorization/authz_unix_test.go b/pkg/authorization/authz_unix_test.go +index 553eab0cb5..835cb70383 100644 +--- a/pkg/authorization/authz_unix_test.go ++++ b/pkg/authorization/authz_unix_test.go +@@ -9,7 +9,7 @@ package authorization // import "github.com/docker/docker/pkg/authorization" + import ( + "bytes" + "encoding/json" +- "io/ioutil" ++ "io" + "net" + "net/http" + "net/http/httptest" +@@ -153,7 +153,7 @@ func TestDrainBody(t *testing.T) { + + for _, test := range tests { + msg := strings.Repeat("a", test.length) +- body, closer, err := drainBody(ioutil.NopCloser(bytes.NewReader([]byte(msg)))) ++ body, closer, err := drainBody(io.NopCloser(bytes.NewReader([]byte(msg)))) + if err != nil { + t.Fatal(err) + } +@@ -163,7 +163,7 @@ func TestDrainBody(t *testing.T) { + if closer == nil { + t.Fatal("Closer must not be nil") + } +- modified, err := ioutil.ReadAll(closer) ++ modified, err := io.ReadAll(closer) + if err != nil { + t.Fatalf("Error must not be nil: '%v'", err) + } +@@ -291,7 +291,7 @@ func (t *authZPluginTestServer) socketAddress() string { + // start starts the test server that implements the plugin + func (t *authZPluginTestServer) start() { + var err error +- t.tmpDir, err = ioutil.TempDir("", "authz") ++ t.tmpDir, err = os.MkdirTemp("", "authz") + if err != nil { + t.t.Fatal(err) + } +@@ -327,7 +327,7 @@ func (t *authZPluginTestServer) stop() { + // auth is a used to record/replay the authentication api messages + func (t *authZPluginTestServer) auth(w http.ResponseWriter, r *http.Request) { + t.recordedRequest = Request{} +- body, err := ioutil.ReadAll(r.Body) ++ body, err := io.ReadAll(r.Body) + if err != nil { + t.t.Fatal(err) + } +diff --git a/pkg/chrootarchive/archive.go b/pkg/chrootarchive/archive.go +index d11cbdf277..427abee7e8 100644 +--- a/pkg/chrootarchive/archive.go ++++ b/pkg/chrootarchive/archive.go +@@ -3,7 +3,6 @@ package chrootarchive // import "github.com/docker/docker/pkg/chrootarchive" + import ( + "fmt" + "io" +- "io/ioutil" + "net" + "os" + "os/user" +@@ -88,7 +87,7 @@ func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions + } + } + +- r := ioutil.NopCloser(tarArchive) ++ r := io.NopCloser(tarArchive) + if decompress { + decompressedArchive, err := archive.DecompressStream(tarArchive) + if err != nil { +diff --git a/pkg/chrootarchive/archive_test.go b/pkg/chrootarchive/archive_test.go +index 0120461d3e..c96c83b072 100644 +--- a/pkg/chrootarchive/archive_test.go ++++ b/pkg/chrootarchive/archive_test.go +@@ -5,7 +5,6 @@ import ( + "fmt" + "hash/crc32" + "io" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -43,7 +42,7 @@ func CopyWithTar(src, dst string) error { + + func TestChrootTarUntar(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootTarUntar") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootTarUntar") + if err != nil { + t.Fatal(err) + } +@@ -52,10 +51,10 @@ func TestChrootTarUntar(t *testing.T) { + if err := system.MkdirAll(src, 0700); err != nil { + t.Fatal(err) + } +- if err := ioutil.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil { + t.Fatal(err) + } +- if err := ioutil.WriteFile(filepath.Join(src, "lolo"), []byte("hello lolo"), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(src, "lolo"), []byte("hello lolo"), 0644); err != nil { + t.Fatal(err) + } + stream, err := archive.Tar(src, archive.Uncompressed) +@@ -75,7 +74,7 @@ func TestChrootTarUntar(t *testing.T) { + // local images) + func TestChrootUntarWithHugeExcludesList(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootUntarHugeExcludes") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootUntarHugeExcludes") + if err != nil { + t.Fatal(err) + } +@@ -84,7 +83,7 @@ func TestChrootUntarWithHugeExcludesList(t *testing.T) { + if err := system.MkdirAll(src, 0700); err != nil { + t.Fatal(err) + } +- if err := ioutil.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil { + t.Fatal(err) + } + stream, err := archive.Tar(src, archive.Uncompressed) +@@ -110,7 +109,7 @@ func TestChrootUntarWithHugeExcludesList(t *testing.T) { + } + + func TestChrootUntarEmptyArchive(t *testing.T) { +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootUntarEmptyArchive") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootUntarEmptyArchive") + if err != nil { + t.Fatal(err) + } +@@ -124,7 +123,7 @@ func prepareSourceDirectory(numberOfFiles int, targetPath string, makeSymLinks b + fileData := []byte("fooo") + for n := 0; n < numberOfFiles; n++ { + fileName := fmt.Sprintf("file-%d", n) +- if err := ioutil.WriteFile(filepath.Join(targetPath, fileName), fileData, 0700); err != nil { ++ if err := os.WriteFile(filepath.Join(targetPath, fileName), fileData, 0700); err != nil { + return 0, err + } + if makeSymLinks { +@@ -138,7 +137,7 @@ func prepareSourceDirectory(numberOfFiles int, targetPath string, makeSymLinks b + } + + func getHash(filename string) (uint32, error) { +- stream, err := ioutil.ReadFile(filename) ++ stream, err := os.ReadFile(filename) + if err != nil { + return 0, err + } +@@ -176,7 +175,7 @@ func compareFiles(src string, dest string) error { + func TestChrootTarUntarWithSymlink(t *testing.T) { + skip.If(t, runtime.GOOS == "windows", "FIXME: figure out why this is failing") + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootTarUntarWithSymlink") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootTarUntarWithSymlink") + if err != nil { + t.Fatal(err) + } +@@ -200,7 +199,7 @@ func TestChrootTarUntarWithSymlink(t *testing.T) { + func TestChrootCopyWithTar(t *testing.T) { + skip.If(t, runtime.GOOS == "windows", "FIXME: figure out why this is failing") + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootCopyWithTar") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootCopyWithTar") + if err != nil { + t.Fatal(err) + } +@@ -247,7 +246,7 @@ func TestChrootCopyWithTar(t *testing.T) { + + func TestChrootCopyFileWithTar(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootCopyFileWithTar") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootCopyFileWithTar") + if err != nil { + t.Fatal(err) + } +@@ -292,7 +291,7 @@ func TestChrootCopyFileWithTar(t *testing.T) { + func TestChrootUntarPath(t *testing.T) { + skip.If(t, runtime.GOOS == "windows", "FIXME: figure out why this is failing") + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootUntarPath") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootUntarPath") + if err != nil { + t.Fatal(err) + } +@@ -318,7 +317,7 @@ func TestChrootUntarPath(t *testing.T) { + buf := new(bytes.Buffer) + buf.ReadFrom(stream) + tarfile := filepath.Join(tmpdir, "src.tar") +- if err := ioutil.WriteFile(tarfile, buf.Bytes(), 0644); err != nil { ++ if err := os.WriteFile(tarfile, buf.Bytes(), 0644); err != nil { + t.Fatal(err) + } + if err := UntarPath(tarfile, dest); err != nil { +@@ -354,7 +353,7 @@ func (s *slowEmptyTarReader) Read(p []byte) (int, error) { + + func TestChrootUntarEmptyArchiveFromSlowReader(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootUntarEmptyArchiveFromSlowReader") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootUntarEmptyArchiveFromSlowReader") + if err != nil { + t.Fatal(err) + } +@@ -371,7 +370,7 @@ func TestChrootUntarEmptyArchiveFromSlowReader(t *testing.T) { + + func TestChrootApplyEmptyArchiveFromSlowReader(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootApplyEmptyArchiveFromSlowReader") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootApplyEmptyArchiveFromSlowReader") + if err != nil { + t.Fatal(err) + } +@@ -388,7 +387,7 @@ func TestChrootApplyEmptyArchiveFromSlowReader(t *testing.T) { + + func TestChrootApplyDotDotFile(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- tmpdir, err := ioutil.TempDir("", "docker-TestChrootApplyDotDotFile") ++ tmpdir, err := os.MkdirTemp("", "docker-TestChrootApplyDotDotFile") + if err != nil { + t.Fatal(err) + } +@@ -397,7 +396,7 @@ func TestChrootApplyDotDotFile(t *testing.T) { + if err := system.MkdirAll(src, 0700); err != nil { + t.Fatal(err) + } +- if err := ioutil.WriteFile(filepath.Join(src, "..gitme"), []byte(""), 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(src, "..gitme"), []byte(""), 0644); err != nil { + t.Fatal(err) + } + stream, err := archive.Tar(src, archive.Uncompressed) +diff --git a/pkg/chrootarchive/archive_unix.go b/pkg/chrootarchive/archive_unix.go +index e292dd576d..b3a8ae1135 100644 +--- a/pkg/chrootarchive/archive_unix.go ++++ b/pkg/chrootarchive/archive_unix.go +@@ -9,7 +9,6 @@ import ( + "flag" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -112,7 +111,7 @@ func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.T + // when `xz -d -c -q | docker-untar ...` failed on docker-untar side, + // we need to exhaust `xz`'s output, otherwise the `xz` side will be + // pending on write pipe forever +- io.Copy(ioutil.Discard, decompressedArchive) ++ io.Copy(io.Discard, decompressedArchive) + + return fmt.Errorf("Error processing tar file(%v): %s", err, output) + } +diff --git a/pkg/chrootarchive/archive_unix_test.go b/pkg/chrootarchive/archive_unix_test.go +index a0ee4b0431..cd557bc5cf 100644 +--- a/pkg/chrootarchive/archive_unix_test.go ++++ b/pkg/chrootarchive/archive_unix_test.go +@@ -7,7 +7,6 @@ import ( + gotar "archive/tar" + "bytes" + "io" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -26,7 +25,7 @@ import ( + // container path that will actually overwrite data on the host + func TestUntarWithMaliciousSymlinks(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(dir) + +@@ -37,7 +36,7 @@ func TestUntarWithMaliciousSymlinks(t *testing.T) { + + // Add a file into a directory above root + // Ensure that we can't access this file while tarring. +- err = ioutil.WriteFile(filepath.Join(dir, "host-file"), []byte("I am a host file"), 0644) ++ err = os.WriteFile(filepath.Join(dir, "host-file"), []byte("I am a host file"), 0644) + assert.NilError(t, err) + + // Create some data which which will be copied into the "container" root into +@@ -47,7 +46,7 @@ func TestUntarWithMaliciousSymlinks(t *testing.T) { + data := filepath.Join(dir, "data") + err = os.MkdirAll(data, 0755) + assert.NilError(t, err) +- err = ioutil.WriteFile(filepath.Join(data, "local-file"), []byte("pwn3d"), 0644) ++ err = os.WriteFile(filepath.Join(data, "local-file"), []byte("pwn3d"), 0644) + assert.NilError(t, err) + + safe := filepath.Join(root, "safe") +@@ -67,7 +66,7 @@ func TestUntarWithMaliciousSymlinks(t *testing.T) { + + // Make sure the "host" file is still in tact + // Before the fix the host file would be overwritten +- hostData, err := ioutil.ReadFile(filepath.Join(dir, "host-file")) ++ hostData, err := os.ReadFile(filepath.Join(dir, "host-file")) + assert.NilError(t, err) + assert.Equal(t, string(hostData), "I am a host file") + +@@ -77,7 +76,7 @@ func TestUntarWithMaliciousSymlinks(t *testing.T) { + err = UntarWithRoot(bufRdr, safe, nil, safe) + assert.NilError(t, err) + +- hostData, err = ioutil.ReadFile(filepath.Join(dir, "host-file")) ++ hostData, err = os.ReadFile(filepath.Join(dir, "host-file")) + assert.NilError(t, err) + assert.Equal(t, string(hostData), "pwn3d") + } +@@ -88,7 +87,7 @@ func TestUntarWithMaliciousSymlinks(t *testing.T) { + // host data into the archive. + func TestTarWithMaliciousSymlinks(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + // defer os.RemoveAll(dir) + t.Log(dir) +@@ -102,7 +101,7 @@ func TestTarWithMaliciousSymlinks(t *testing.T) { + + // Add a file into a directory above root + // Ensure that we can't access this file while tarring. +- err = ioutil.WriteFile(filepath.Join(dir, "host-file"), hostFileData, 0644) ++ err = os.WriteFile(filepath.Join(dir, "host-file"), hostFileData, 0644) + assert.NilError(t, err) + + safe := filepath.Join(root, "safe") +diff --git a/pkg/chrootarchive/chroot_linux.go b/pkg/chrootarchive/chroot_linux.go +index 1c560ce59f..a4e3920113 100644 +--- a/pkg/chrootarchive/chroot_linux.go ++++ b/pkg/chrootarchive/chroot_linux.go +@@ -2,7 +2,6 @@ package chrootarchive // import "github.com/docker/docker/pkg/chrootarchive" + + import ( + "fmt" +- "io/ioutil" + "os" + "path/filepath" + +@@ -44,7 +43,7 @@ func chroot(path string) (err error) { + } + + // setup oldRoot for pivot_root +- pivotDir, err := ioutil.TempDir(path, ".pivot_root") ++ pivotDir, err := os.MkdirTemp(path, ".pivot_root") + if err != nil { + return fmt.Errorf("Error setting up pivot dir: %v", err) + } +diff --git a/pkg/chrootarchive/diff_unix.go b/pkg/chrootarchive/diff_unix.go +index f0e9233ba3..18d028af18 100644 +--- a/pkg/chrootarchive/diff_unix.go ++++ b/pkg/chrootarchive/diff_unix.go +@@ -9,7 +9,6 @@ import ( + "flag" + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -57,7 +56,7 @@ func applyLayer() { + options.InUserNS = true + } + +- if tmpDir, err = ioutil.TempDir("/", "temp-docker-extract"); err != nil { ++ if tmpDir, err = os.MkdirTemp("/", "temp-docker-extract"); err != nil { + fatal(err) + } + +diff --git a/pkg/chrootarchive/diff_windows.go b/pkg/chrootarchive/diff_windows.go +index 8f3f3a4a8a..f423419d3c 100644 +--- a/pkg/chrootarchive/diff_windows.go ++++ b/pkg/chrootarchive/diff_windows.go +@@ -3,7 +3,6 @@ package chrootarchive // import "github.com/docker/docker/pkg/chrootarchive" + import ( + "fmt" + "io" +- "io/ioutil" + "os" + "path/filepath" + +@@ -30,7 +29,7 @@ func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions + layer = decompressed + } + +- tmpDir, err := ioutil.TempDir(os.Getenv("temp"), "temp-docker-extract") ++ tmpDir, err := os.MkdirTemp(os.Getenv("temp"), "temp-docker-extract") + if err != nil { + return 0, fmt.Errorf("ApplyLayer failed to create temp-docker-extract under %s. %s", dest, err) + } +diff --git a/pkg/chrootarchive/init_unix.go b/pkg/chrootarchive/init_unix.go +index 07cfc1c653..0746c1cb97 100644 +--- a/pkg/chrootarchive/init_unix.go ++++ b/pkg/chrootarchive/init_unix.go +@@ -6,7 +6,6 @@ package chrootarchive // import "github.com/docker/docker/pkg/chrootarchive" + import ( + "fmt" + "io" +- "io/ioutil" + "os" + + "github.com/docker/docker/pkg/reexec" +@@ -26,5 +25,5 @@ func fatal(err error) { + // flush consumes all the bytes from the reader discarding + // any errors + func flush(r io.Reader) (bytes int64, err error) { +- return io.Copy(ioutil.Discard, r) ++ return io.Copy(io.Discard, r) + } +diff --git a/pkg/directory/directory.go b/pkg/directory/directory.go +index 51d4a6ea22..71e8cfee77 100644 +--- a/pkg/directory/directory.go ++++ b/pkg/directory/directory.go +@@ -1,7 +1,6 @@ + package directory // import "github.com/docker/docker/pkg/directory" + + import ( +- "io/ioutil" + "os" + "path/filepath" + ) +@@ -9,7 +8,7 @@ import ( + // MoveToSubdir moves all contents of a directory to a subdirectory underneath the original path + func MoveToSubdir(oldpath, subdir string) error { + +- infos, err := ioutil.ReadDir(oldpath) ++ infos, err := os.ReadDir(oldpath) + if err != nil { + return err + } +diff --git a/pkg/directory/directory_test.go b/pkg/directory/directory_test.go +index 04bb5d8d02..8477a202fe 100644 +--- a/pkg/directory/directory_test.go ++++ b/pkg/directory/directory_test.go +@@ -2,7 +2,6 @@ package directory // import "github.com/docker/docker/pkg/directory" + + import ( + "context" +- "io/ioutil" + "os" + "path/filepath" + "reflect" +@@ -14,7 +13,7 @@ import ( + func TestSizeEmpty(t *testing.T) { + var dir string + var err error +- if dir, err = ioutil.TempDir(os.TempDir(), "testSizeEmptyDirectory"); err != nil { ++ if dir, err = os.MkdirTemp(os.TempDir(), "testSizeEmptyDirectory"); err != nil { + t.Fatalf("failed to create directory: %s", err) + } + +@@ -28,12 +27,12 @@ func TestSizeEmpty(t *testing.T) { + func TestSizeEmptyFile(t *testing.T) { + var dir string + var err error +- if dir, err = ioutil.TempDir(os.TempDir(), "testSizeEmptyFile"); err != nil { ++ if dir, err = os.MkdirTemp(os.TempDir(), "testSizeEmptyFile"); err != nil { + t.Fatalf("failed to create directory: %s", err) + } + + var file *os.File +- if file, err = ioutil.TempFile(dir, "file"); err != nil { ++ if file, err = os.CreateTemp(dir, "file"); err != nil { + t.Fatalf("failed to create file: %s", err) + } + +@@ -47,12 +46,12 @@ func TestSizeEmptyFile(t *testing.T) { + func TestSizeNonemptyFile(t *testing.T) { + var dir string + var err error +- if dir, err = ioutil.TempDir(os.TempDir(), "testSizeNonemptyFile"); err != nil { ++ if dir, err = os.MkdirTemp(os.TempDir(), "testSizeNonemptyFile"); err != nil { + t.Fatalf("failed to create directory: %s", err) + } + + var file *os.File +- if file, err = ioutil.TempFile(dir, "file"); err != nil { ++ if file, err = os.CreateTemp(dir, "file"); err != nil { + t.Fatalf("failed to create file: %s", err) + } + +@@ -69,10 +68,10 @@ func TestSizeNonemptyFile(t *testing.T) { + func TestSizeNestedDirectoryEmpty(t *testing.T) { + var dir string + var err error +- if dir, err = ioutil.TempDir(os.TempDir(), "testSizeNestedDirectoryEmpty"); err != nil { ++ if dir, err = os.MkdirTemp(os.TempDir(), "testSizeNestedDirectoryEmpty"); err != nil { + t.Fatalf("failed to create directory: %s", err) + } +- if dir, err = ioutil.TempDir(dir, "nested"); err != nil { ++ if dir, err = os.MkdirTemp(dir, "nested"); err != nil { + t.Fatalf("failed to create nested directory: %s", err) + } + +@@ -86,15 +85,15 @@ func TestSizeNestedDirectoryEmpty(t *testing.T) { + func TestSizeFileAndNestedDirectoryEmpty(t *testing.T) { + var dir string + var err error +- if dir, err = ioutil.TempDir(os.TempDir(), "testSizeFileAndNestedDirectoryEmpty"); err != nil { ++ if dir, err = os.MkdirTemp(os.TempDir(), "testSizeFileAndNestedDirectoryEmpty"); err != nil { + t.Fatalf("failed to create directory: %s", err) + } +- if dir, err = ioutil.TempDir(dir, "nested"); err != nil { ++ if dir, err = os.MkdirTemp(dir, "nested"); err != nil { + t.Fatalf("failed to create nested directory: %s", err) + } + + var file *os.File +- if file, err = ioutil.TempFile(dir, "file"); err != nil { ++ if file, err = os.CreateTemp(dir, "file"); err != nil { + t.Fatalf("failed to create file: %s", err) + } + +@@ -111,15 +110,15 @@ func TestSizeFileAndNestedDirectoryEmpty(t *testing.T) { + func TestSizeFileAndNestedDirectoryNonempty(t *testing.T) { + var dir, dirNested string + var err error +- if dir, err = ioutil.TempDir(os.TempDir(), "TestSizeFileAndNestedDirectoryNonempty"); err != nil { ++ if dir, err = os.MkdirTemp(os.TempDir(), "TestSizeFileAndNestedDirectoryNonempty"); err != nil { + t.Fatalf("failed to create directory: %s", err) + } +- if dirNested, err = ioutil.TempDir(dir, "nested"); err != nil { ++ if dirNested, err = os.MkdirTemp(dir, "nested"); err != nil { + t.Fatalf("failed to create nested directory: %s", err) + } + + var file *os.File +- if file, err = ioutil.TempFile(dir, "file"); err != nil { ++ if file, err = os.CreateTemp(dir, "file"); err != nil { + t.Fatalf("failed to create file: %s", err) + } + +@@ -127,7 +126,7 @@ func TestSizeFileAndNestedDirectoryNonempty(t *testing.T) { + file.Write(data) + + var nestedFile *os.File +- if nestedFile, err = ioutil.TempFile(dirNested, "file"); err != nil { ++ if nestedFile, err = os.CreateTemp(dirNested, "file"); err != nil { + t.Fatalf("failed to create file in nested directory: %s", err) + } + +@@ -145,11 +144,11 @@ func TestMoveToSubdir(t *testing.T) { + var outerDir, subDir string + var err error + +- if outerDir, err = ioutil.TempDir(os.TempDir(), "TestMoveToSubdir"); err != nil { ++ if outerDir, err = os.MkdirTemp(os.TempDir(), "TestMoveToSubdir"); err != nil { + t.Fatalf("failed to create directory: %v", err) + } + +- if subDir, err = ioutil.TempDir(outerDir, "testSub"); err != nil { ++ if subDir, err = os.MkdirTemp(outerDir, "testSub"); err != nil { + t.Fatalf("failed to create subdirectory: %v", err) + } + +@@ -168,7 +167,7 @@ func TestMoveToSubdir(t *testing.T) { + t.Fatalf("Error during migration of content to subdirectory: %v", err) + } + // validate that the files were moved to the subdirectory +- infos, err := ioutil.ReadDir(subDir) ++ infos, err := os.ReadDir(subDir) + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/discovery/file/file.go b/pkg/discovery/file/file.go +index 1494af485f..f5571db5d6 100644 +--- a/pkg/discovery/file/file.go ++++ b/pkg/discovery/file/file.go +@@ -2,7 +2,7 @@ package file // import "github.com/docker/docker/pkg/discovery/file" + + import ( + "fmt" +- "io/ioutil" ++ "os" + "strings" + "time" + +@@ -51,7 +51,7 @@ func parseFileContent(content []byte) []string { + } + + func (s *Discovery) fetch() (discovery.Entries, error) { +- fileContent, err := ioutil.ReadFile(s.path) ++ fileContent, err := os.ReadFile(s.path) + if err != nil { + return nil, fmt.Errorf("failed to read '%s': %v", s.path, err) + } +diff --git a/pkg/discovery/file/file_test.go b/pkg/discovery/file/file_test.go +index 0418c9ecc4..fdd5715a51 100644 +--- a/pkg/discovery/file/file_test.go ++++ b/pkg/discovery/file/file_test.go +@@ -1,7 +1,6 @@ + package file // import "github.com/docker/docker/pkg/discovery/file" + + import ( +- "io/ioutil" + "os" + "testing" + +@@ -74,7 +73,7 @@ func (s *DiscoverySuite) TestWatch(c *testing.T) { + } + + // Create a temporary file and remove it. +- tmp, err := ioutil.TempFile(os.TempDir(), "discovery-file-test") ++ tmp, err := os.CreateTemp(os.TempDir(), "discovery-file-test") + assert.Assert(c, err == nil) + assert.Assert(c, tmp.Close() == nil) + assert.Assert(c, os.Remove(tmp.Name()) == nil) +@@ -94,7 +93,7 @@ func (s *DiscoverySuite) TestWatch(c *testing.T) { + }() + + // Write the file and make sure we get the expected value back. +- assert.Assert(c, ioutil.WriteFile(tmp.Name(), []byte(data), 0600) == nil) ++ assert.Assert(c, os.WriteFile(tmp.Name(), []byte(data), 0600) == nil) + assert.DeepEqual(c, <-ch, expected) + + // Add a new entry and look it up. +diff --git a/pkg/discovery/kv/kv_test.go b/pkg/discovery/kv/kv_test.go +index 2c42449b6f..a944e3cf3c 100644 +--- a/pkg/discovery/kv/kv_test.go ++++ b/pkg/discovery/kv/kv_test.go +@@ -2,7 +2,6 @@ package kv // import "github.com/docker/docker/pkg/discovery/kv" + + import ( + "errors" +- "io/ioutil" + "os" + "path" + "testing" +@@ -181,12 +180,12 @@ dyT7ut01PL6RaW4SeQWtrJIVQaM6vF3pprMKqlc5XihOGAmVqH7rQx9rtQB5TicL + BFrwkQE4HQtQBV60hYQUzzlSk44VFDz+jxIEtacRHaomDRh2FtOTz+I= + -----END RSA PRIVATE KEY----- + ` +- certFile, err := ioutil.TempFile("", "cert") ++ certFile, err := os.CreateTemp("", "cert") + assert.Assert(c, err == nil) + defer os.Remove(certFile.Name()) + certFile.Write([]byte(cert)) + certFile.Close() +- keyFile, err := ioutil.TempFile("", "key") ++ keyFile, err := os.CreateTemp("", "key") + assert.Assert(c, err == nil) + defer os.Remove(keyFile.Name()) + keyFile.Write([]byte(key)) +diff --git a/pkg/filenotify/poller_test.go b/pkg/filenotify/poller_test.go +index ead2504372..53ec7b8508 100644 +--- a/pkg/filenotify/poller_test.go ++++ b/pkg/filenotify/poller_test.go +@@ -2,7 +2,6 @@ package filenotify // import "github.com/docker/docker/pkg/filenotify" + + import ( + "fmt" +- "io/ioutil" + "os" + "runtime" + "testing" +@@ -21,7 +20,7 @@ func TestPollerAddRemove(t *testing.T) { + t.Fatal("should have gotten error when removing non-existent watch") + } + +- f, err := ioutil.TempFile("", "asdf") ++ f, err := os.CreateTemp("", "asdf") + if err != nil { + t.Fatal(err) + } +@@ -42,7 +41,7 @@ func TestPollerEvent(t *testing.T) { + } + w := NewPollingWatcher() + +- f, err := ioutil.TempFile("", "test-poller") ++ f, err := os.CreateTemp("", "test-poller") + if err != nil { + t.Fatal("error creating temp file") + } +@@ -61,7 +60,7 @@ func TestPollerEvent(t *testing.T) { + default: + } + +- if err := ioutil.WriteFile(f.Name(), []byte("hello"), 0600); err != nil { ++ if err := os.WriteFile(f.Name(), []byte("hello"), 0600); err != nil { + t.Fatal(err) + } + assertFileMode(t, f.Name(), 0600) +@@ -95,7 +94,7 @@ func TestPollerClose(t *testing.T) { + t.Fatal(err) + } + +- f, err := ioutil.TempFile("", "asdf") ++ f, err := os.CreateTemp("", "asdf") + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/fileutils/fileutils_test.go b/pkg/fileutils/fileutils_test.go +index 36064b6f5f..a9d13228f7 100644 +--- a/pkg/fileutils/fileutils_test.go ++++ b/pkg/fileutils/fileutils_test.go +@@ -2,7 +2,6 @@ package fileutils // import "github.com/docker/docker/pkg/fileutils" + + import ( + "fmt" +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -16,7 +15,7 @@ import ( + + // CopyFile with invalid src + func TestCopyFileWithInvalidSrc(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") // #nosec G303 ++ tempFolder, err := os.MkdirTemp("", "docker-fileutils-test") // #nosec G303 + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) +@@ -33,13 +32,13 @@ func TestCopyFileWithInvalidSrc(t *testing.T) { + + // CopyFile with invalid dest + func TestCopyFileWithInvalidDest(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") ++ tempFolder, err := os.MkdirTemp("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) + } + src := path.Join(tempFolder, "file") +- err = ioutil.WriteFile(src, []byte("content"), 0740) ++ err = os.WriteFile(src, []byte("content"), 0740) + if err != nil { + t.Fatal(err) + } +@@ -55,13 +54,13 @@ func TestCopyFileWithInvalidDest(t *testing.T) { + + // CopyFile with same src and dest + func TestCopyFileWithSameSrcAndDest(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") ++ tempFolder, err := os.MkdirTemp("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) + } + file := path.Join(tempFolder, "file") +- err = ioutil.WriteFile(file, []byte("content"), 0740) ++ err = os.WriteFile(file, []byte("content"), 0740) + if err != nil { + t.Fatal(err) + } +@@ -76,7 +75,7 @@ func TestCopyFileWithSameSrcAndDest(t *testing.T) { + + // CopyFile with same src and dest but path is different and not clean + func TestCopyFileWithSameSrcAndDestWithPathNameDifferent(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") ++ tempFolder, err := os.MkdirTemp("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) +@@ -88,7 +87,7 @@ func TestCopyFileWithSameSrcAndDestWithPathNameDifferent(t *testing.T) { + } + file := path.Join(testFolder, "file") + sameFile := testFolder + "/../test/file" +- err = ioutil.WriteFile(file, []byte("content"), 0740) ++ err = os.WriteFile(file, []byte("content"), 0740) + if err != nil { + t.Fatal(err) + } +@@ -102,15 +101,15 @@ func TestCopyFileWithSameSrcAndDestWithPathNameDifferent(t *testing.T) { + } + + func TestCopyFile(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") ++ tempFolder, err := os.MkdirTemp("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) + } + src := path.Join(tempFolder, "src") + dest := path.Join(tempFolder, "dest") +- ioutil.WriteFile(src, []byte("content"), 0777) +- ioutil.WriteFile(dest, []byte("destContent"), 0777) ++ os.WriteFile(src, []byte("content"), 0777) ++ os.WriteFile(dest, []byte("destContent"), 0777) + bytes, err := CopyFile(src, dest) + if err != nil { + t.Fatal(err) +@@ -118,7 +117,7 @@ func TestCopyFile(t *testing.T) { + if bytes != 7 { + t.Fatalf("Should have written %d bytes but wrote %d", 7, bytes) + } +- actual, err := ioutil.ReadFile(dest) ++ actual, err := os.ReadFile(dest) + if err != nil { + t.Fatal(err) + } +@@ -455,7 +454,7 @@ func TestCleanPatternsErrorSingleException(t *testing.T) { + } + + func TestCreateIfNotExistsDir(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") ++ tempFolder, err := os.MkdirTemp("", "docker-fileutils-test") + if err != nil { + t.Fatal(err) + } +@@ -477,7 +476,7 @@ func TestCreateIfNotExistsDir(t *testing.T) { + } + + func TestCreateIfNotExistsFile(t *testing.T) { +- tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") ++ tempFolder, err := os.MkdirTemp("", "docker-fileutils-test") + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/fileutils/fileutils_unix.go b/pkg/fileutils/fileutils_unix.go +index af0c26b614..f782b4266a 100644 +--- a/pkg/fileutils/fileutils_unix.go ++++ b/pkg/fileutils/fileutils_unix.go +@@ -5,7 +5,6 @@ package fileutils // import "github.com/docker/docker/pkg/fileutils" + + import ( + "fmt" +- "io/ioutil" + "os" + + "github.com/sirupsen/logrus" +@@ -14,7 +13,7 @@ import ( + // GetTotalUsedFds Returns the number of used File Descriptors by + // reading it via /proc filesystem. + func GetTotalUsedFds() int { +- if fds, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil { ++ if fds, err := os.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil { + logrus.Errorf("Error opening /proc/%d/fd: %s", os.Getpid(), err) + } else { + return len(fds) +diff --git a/pkg/fsutils/fsutils_linux.go b/pkg/fsutils/fsutils_linux.go +index 104211adea..d9a7760963 100644 +--- a/pkg/fsutils/fsutils_linux.go ++++ b/pkg/fsutils/fsutils_linux.go +@@ -2,7 +2,6 @@ package fsutils // import "github.com/docker/docker/pkg/fsutils" + + import ( + "fmt" +- "io/ioutil" + "os" + "unsafe" + +@@ -10,14 +9,14 @@ import ( + ) + + func locateDummyIfEmpty(path string) (string, error) { +- children, err := ioutil.ReadDir(path) ++ children, err := os.ReadDir(path) + if err != nil { + return "", err + } + if len(children) != 0 { + return "", nil + } +- dummyFile, err := ioutil.TempFile(path, "fsutils-dummy") ++ dummyFile, err := os.CreateTemp(path, "fsutils-dummy") + if err != nil { + return "", err + } +diff --git a/pkg/fsutils/fsutils_linux_test.go b/pkg/fsutils/fsutils_linux_test.go +index b627b3fe4d..f7af8e8677 100644 +--- a/pkg/fsutils/fsutils_linux_test.go ++++ b/pkg/fsutils/fsutils_linux_test.go +@@ -4,7 +4,6 @@ + package fsutils // import "github.com/docker/docker/pkg/fsutils" + + import ( +- "io/ioutil" + "os" + "os/exec" + "testing" +@@ -20,7 +19,7 @@ func testSupportsDType(t *testing.T, expected bool, mkfsCommand string, mkfsArg + + // create a sparse image + imageSize := int64(32 * 1024 * 1024) +- imageFile, err := ioutil.TempFile("", "fsutils-image") ++ imageFile, err := os.CreateTemp("", "fsutils-image") + if err != nil { + t.Fatal(err) + } +@@ -37,7 +36,7 @@ func testSupportsDType(t *testing.T, expected bool, mkfsCommand string, mkfsArg + } + + // create a mountpoint +- mountpoint, err := ioutil.TempDir("", "fsutils-mountpoint") ++ mountpoint, err := os.MkdirTemp("", "fsutils-mountpoint") + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/idtools/idtools_unix_test.go b/pkg/idtools/idtools_unix_test.go +index f1670a6fec..c43ed6fc8d 100644 +--- a/pkg/idtools/idtools_unix_test.go ++++ b/pkg/idtools/idtools_unix_test.go +@@ -5,7 +5,6 @@ package idtools // import "github.com/docker/docker/pkg/idtools" + + import ( + "fmt" +- "io/ioutil" + "os" + "os/user" + "path/filepath" +@@ -28,7 +27,7 @@ type node struct { + + func TestMkdirAllAndChown(t *testing.T) { + RequiresRoot(t) +- dirName, err := ioutil.TempDir("", "mkdirall") ++ dirName, err := os.MkdirTemp("", "mkdirall") + if err != nil { + t.Fatalf("Couldn't create temp dir: %v", err) + } +@@ -89,7 +88,7 @@ func TestMkdirAllAndChown(t *testing.T) { + + func TestMkdirAllAndChownNew(t *testing.T) { + RequiresRoot(t) +- dirName, err := ioutil.TempDir("", "mkdirnew") ++ dirName, err := os.MkdirTemp("", "mkdirnew") + assert.NilError(t, err) + defer os.RemoveAll(dirName) + +@@ -130,7 +129,7 @@ func TestMkdirAllAndChownNew(t *testing.T) { + + func TestMkdirAndChown(t *testing.T) { + RequiresRoot(t) +- dirName, err := ioutil.TempDir("", "mkdir") ++ dirName, err := os.MkdirTemp("", "mkdir") + if err != nil { + t.Fatalf("Couldn't create temp dir: %v", err) + } +@@ -191,7 +190,7 @@ func buildTree(base string, tree map[string]node) error { + func readTree(base, root string) (map[string]node, error) { + tree := make(map[string]node) + +- dirInfos, err := ioutil.ReadDir(base) ++ dirInfos, err := os.ReadDir(base) + if err != nil { + return nil, fmt.Errorf("Couldn't read directory entries for %q: %v", base, err) + } +@@ -240,7 +239,7 @@ func delUser(t *testing.T, name string) { + } + + func TestParseSubidFileWithNewlinesAndComments(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "parsesubid") ++ tmpDir, err := os.MkdirTemp("", "parsesubid") + if err != nil { + t.Fatal(err) + } +@@ -249,7 +248,7 @@ func TestParseSubidFileWithNewlinesAndComments(t *testing.T) { + # empty default subuid/subgid file + + dockremap:231072:65536` +- if err := ioutil.WriteFile(fnamePath, []byte(fcontent), 0644); err != nil { ++ if err := os.WriteFile(fnamePath, []byte(fcontent), 0644); err != nil { + t.Fatal(err) + } + ranges, err := parseSubidFile(fnamePath, "dockremap") +@@ -328,7 +327,7 @@ func TestNewIDMappings(t *testing.T) { + rootUID, rootGID, err := GetRootUIDGID(idMapping.UIDs(), idMapping.GIDs()) + assert.Check(t, err) + +- dirName, err := ioutil.TempDir("", "mkdirall") ++ dirName, err := os.MkdirTemp("", "mkdirall") + assert.Check(t, err, "Couldn't create temp directory") + defer os.RemoveAll(dirName) + +@@ -378,7 +377,7 @@ func TestLookupUserAndGroupThatDoesNotExist(t *testing.T) { + // returns a correct error in case a directory which it is about to create + // already exists but is a file (rather than a directory). + func TestMkdirIsNotDir(t *testing.T) { +- file, err := ioutil.TempFile("", t.Name()) ++ file, err := os.CreateTemp("", t.Name()) + if err != nil { + t.Fatalf("Couldn't create temp dir: %v", err) + } +diff --git a/pkg/ioutils/fswriters.go b/pkg/ioutils/fswriters.go +index 534d66ac26..82671d8cd5 100644 +--- a/pkg/ioutils/fswriters.go ++++ b/pkg/ioutils/fswriters.go +@@ -2,7 +2,6 @@ package ioutils // import "github.com/docker/docker/pkg/ioutils" + + import ( + "io" +- "io/ioutil" + "os" + "path/filepath" + ) +@@ -11,7 +10,7 @@ import ( + // temporary file and closing it atomically changes the temporary file to + // destination path. Writing and closing concurrently is not allowed. + func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, error) { +- f, err := ioutil.TempFile(filepath.Dir(filename), ".tmp-"+filepath.Base(filename)) ++ f, err := os.CreateTemp(filepath.Dir(filename), ".tmp-"+filepath.Base(filename)) + if err != nil { + return nil, err + } +@@ -94,7 +93,7 @@ type AtomicWriteSet struct { + // commit. If no temporary directory is given the system + // default is used. + func NewAtomicWriteSet(tmpDir string) (*AtomicWriteSet, error) { +- td, err := ioutil.TempDir(tmpDir, "write-set-") ++ td, err := os.MkdirTemp(tmpDir, "write-set-") + if err != nil { + return nil, err + } +diff --git a/pkg/ioutils/fswriters_test.go b/pkg/ioutils/fswriters_test.go +index bce68c2f71..d635561388 100644 +--- a/pkg/ioutils/fswriters_test.go ++++ b/pkg/ioutils/fswriters_test.go +@@ -2,7 +2,6 @@ package ioutils // import "github.com/docker/docker/pkg/ioutils" + + import ( + "bytes" +- "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -21,7 +20,7 @@ func init() { + } + + func TestAtomicWriteToFile(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "atomic-writers-test") ++ tmpDir, err := os.MkdirTemp("", "atomic-writers-test") + if err != nil { + t.Fatalf("Error when creating temporary directory: %s", err) + } +@@ -32,7 +31,7 @@ func TestAtomicWriteToFile(t *testing.T) { + t.Fatalf("Error writing to file: %v", err) + } + +- actual, err := ioutil.ReadFile(filepath.Join(tmpDir, "foo")) ++ actual, err := os.ReadFile(filepath.Join(tmpDir, "foo")) + if err != nil { + t.Fatalf("Error reading from file: %v", err) + } +@@ -51,7 +50,7 @@ func TestAtomicWriteToFile(t *testing.T) { + } + + func TestAtomicWriteSetCommit(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "atomic-writerset-test") ++ tmpDir, err := os.MkdirTemp("", "atomic-writerset-test") + if err != nil { + t.Fatalf("Error when creating temporary directory: %s", err) + } +@@ -72,7 +71,7 @@ func TestAtomicWriteSetCommit(t *testing.T) { + t.Fatalf("Error writing to file: %v", err) + } + +- if _, err := ioutil.ReadFile(filepath.Join(targetDir, "foo")); err == nil { ++ if _, err := os.ReadFile(filepath.Join(targetDir, "foo")); err == nil { + t.Fatalf("Expected error reading file where should not exist") + } + +@@ -80,7 +79,7 @@ func TestAtomicWriteSetCommit(t *testing.T) { + t.Fatalf("Error committing file: %s", err) + } + +- actual, err := ioutil.ReadFile(filepath.Join(targetDir, "foo")) ++ actual, err := os.ReadFile(filepath.Join(targetDir, "foo")) + if err != nil { + t.Fatalf("Error reading from file: %v", err) + } +@@ -100,7 +99,7 @@ func TestAtomicWriteSetCommit(t *testing.T) { + } + + func TestAtomicWriteSetCancel(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "atomic-writerset-test") ++ tmpDir, err := os.MkdirTemp("", "atomic-writerset-test") + if err != nil { + t.Fatalf("Error when creating temporary directory: %s", err) + } +@@ -124,7 +123,7 @@ func TestAtomicWriteSetCancel(t *testing.T) { + t.Fatalf("Error committing file: %s", err) + } + +- if _, err := ioutil.ReadFile(filepath.Join(tmpDir, "target", "foo")); err == nil { ++ if _, err := os.ReadFile(filepath.Join(tmpDir, "target", "foo")); err == nil { + t.Fatalf("Expected error reading file where should not exist") + } else if !os.IsNotExist(err) { + t.Fatalf("Unexpected error reading file: %s", err) +diff --git a/pkg/ioutils/readers_test.go b/pkg/ioutils/readers_test.go +index 949e28739f..0d906318dc 100644 +--- a/pkg/ioutils/readers_test.go ++++ b/pkg/ioutils/readers_test.go +@@ -3,7 +3,7 @@ package ioutils // import "github.com/docker/docker/pkg/ioutils" + import ( + "context" + "fmt" +- "io/ioutil" ++ "io" + "strings" + "testing" + "time" +@@ -82,7 +82,7 @@ func (p *perpetualReader) Read(buf []byte) (n int, err error) { + func TestCancelReadCloser(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() +- cancelReadCloser := NewCancelReadCloser(ctx, ioutil.NopCloser(&perpetualReader{})) ++ cancelReadCloser := NewCancelReadCloser(ctx, io.NopCloser(&perpetualReader{})) + for { + var buf [128]byte + _, err := cancelReadCloser.Read(buf[:]) +diff --git a/pkg/ioutils/temp_unix.go b/pkg/ioutils/temp_unix.go +index 4e67ec2f53..7489122309 100644 +--- a/pkg/ioutils/temp_unix.go ++++ b/pkg/ioutils/temp_unix.go +@@ -3,9 +3,9 @@ + + package ioutils // import "github.com/docker/docker/pkg/ioutils" + +-import "io/ioutil" ++import "os" + +-// TempDir on Unix systems is equivalent to ioutil.TempDir. ++// TempDir on Unix systems is equivalent to os.MkdirTemp. + func TempDir(dir, prefix string) (string, error) { +- return ioutil.TempDir(dir, prefix) ++ return os.MkdirTemp(dir, prefix) + } +diff --git a/pkg/ioutils/temp_windows.go b/pkg/ioutils/temp_windows.go +index ecaba2e36d..a57fd9af6a 100644 +--- a/pkg/ioutils/temp_windows.go ++++ b/pkg/ioutils/temp_windows.go +@@ -1,14 +1,14 @@ + package ioutils // import "github.com/docker/docker/pkg/ioutils" + + import ( +- "io/ioutil" ++ "os" + + "github.com/docker/docker/pkg/longpath" + ) + +-// TempDir is the equivalent of ioutil.TempDir, except that the result is in Windows longpath format. ++// TempDir is the equivalent of os.MkdirTemp, except that the result is in Windows longpath format. + func TempDir(dir, prefix string) (string, error) { +- tempDir, err := ioutil.TempDir(dir, prefix) ++ tempDir, err := os.MkdirTemp(dir, prefix) + if err != nil { + return "", err + } +diff --git a/pkg/parsers/operatingsystem/operatingsystem_linux.go b/pkg/parsers/operatingsystem/operatingsystem_linux.go +index c3b0634bcf..1abddad9f4 100644 +--- a/pkg/parsers/operatingsystem/operatingsystem_linux.go ++++ b/pkg/parsers/operatingsystem/operatingsystem_linux.go +@@ -6,7 +6,6 @@ import ( + "bufio" + "bytes" + "fmt" +- "io/ioutil" + "os" + "strings" + ) +@@ -70,7 +69,7 @@ func getValueFromOsRelease(key string) (string, error) { + + // IsContainerized returns true if we are running inside a container. + func IsContainerized() (bool, error) { +- b, err := ioutil.ReadFile(proc1Cgroup) ++ b, err := os.ReadFile(proc1Cgroup) + if err != nil { + return false, err + } +diff --git a/pkg/parsers/operatingsystem/operatingsystem_linux_test.go b/pkg/parsers/operatingsystem/operatingsystem_linux_test.go +index 2e55617594..d0ca93e971 100644 +--- a/pkg/parsers/operatingsystem/operatingsystem_linux_test.go ++++ b/pkg/parsers/operatingsystem/operatingsystem_linux_test.go +@@ -4,7 +4,6 @@ + package operatingsystem // import "github.com/docker/docker/pkg/parsers/operatingsystem" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -140,7 +139,7 @@ func runEtcReleaseParsingTests(t *testing.T, tests []EtcReleaseParsingTest, pars + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { +- if err := ioutil.WriteFile(etcOsRelease, []byte(test.content), 0600); err != nil { ++ if err := os.WriteFile(etcOsRelease, []byte(test.content), 0600); err != nil { + t.Fatalf("failed to write to %s: %v", etcOsRelease, err) + } + s, err := parsingFunc() +@@ -203,7 +202,7 @@ func TestIsContainerized(t *testing.T) { + proc1Cgroup = backup + }() + +- if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroup, 0600); err != nil { ++ if err := os.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroup, 0600); err != nil { + t.Fatalf("failed to write to %s: %v", proc1Cgroup, err) + } + inContainer, err := IsContainerized() +@@ -214,7 +213,7 @@ func TestIsContainerized(t *testing.T) { + t.Fatal("Wrongly assuming containerized") + } + +- if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroupsystemd226, 0600); err != nil { ++ if err := os.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroupsystemd226, 0600); err != nil { + t.Fatalf("failed to write to %s: %v", proc1Cgroup, err) + } + inContainer, err = IsContainerized() +@@ -225,7 +224,7 @@ func TestIsContainerized(t *testing.T) { + t.Fatal("Wrongly assuming containerized for systemd /init.scope cgroup layout") + } + +- if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1CgroupNotSystemd, 0600); err != nil { ++ if err := os.WriteFile(proc1Cgroup, nonContainerizedProc1CgroupNotSystemd, 0600); err != nil { + t.Fatalf("failed to write to %s: %v", proc1Cgroup, err) + } + inContainer, err = IsContainerized() +@@ -236,7 +235,7 @@ func TestIsContainerized(t *testing.T) { + t.Fatal("Wrongly assuming non-containerized") + } + +- if err := ioutil.WriteFile(proc1Cgroup, containerizedProc1Cgroup, 0600); err != nil { ++ if err := os.WriteFile(proc1Cgroup, containerizedProc1Cgroup, 0600); err != nil { + t.Fatalf("failed to write to %s: %v", proc1Cgroup, err) + } + inContainer, err = IsContainerized() +@@ -268,7 +267,7 @@ HOME_URL="http://www.gentoo.org/" + SUPPORT_URL="http://www.gentoo.org/main/en/support.xml" + BUG_REPORT_URL="https://bugs.gentoo.org/" + ` +- if err := ioutil.WriteFile(altOsRelease, []byte(content), 0600); err != nil { ++ if err := os.WriteFile(altOsRelease, []byte(content), 0600); err != nil { + t.Fatalf("failed to write to %s: %v", etcOsRelease, err) + } + s, err := GetOperatingSystem() +diff --git a/pkg/pidfile/pidfile.go b/pkg/pidfile/pidfile.go +index d809ee4860..a4dac5d025 100644 +--- a/pkg/pidfile/pidfile.go ++++ b/pkg/pidfile/pidfile.go +@@ -5,7 +5,6 @@ package pidfile // import "github.com/docker/docker/pkg/pidfile" + + import ( + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "strconv" +@@ -20,7 +19,7 @@ type PIDFile struct { + } + + func checkPIDFileAlreadyExists(path string) error { +- if pidByte, err := ioutil.ReadFile(path); err == nil { ++ if pidByte, err := os.ReadFile(path); err == nil { + pidString := strings.TrimSpace(string(pidByte)) + if pid, err := strconv.Atoi(pidString); err == nil { + if processExists(pid) { +@@ -40,7 +39,7 @@ func New(path string) (*PIDFile, error) { + if err := system.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil { + return nil, err + } +- if err := ioutil.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil { ++ if err := os.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil { + return nil, err + } + +diff --git a/pkg/pidfile/pidfile_test.go b/pkg/pidfile/pidfile_test.go +index cd9878e1e4..59860350a7 100644 +--- a/pkg/pidfile/pidfile_test.go ++++ b/pkg/pidfile/pidfile_test.go +@@ -1,14 +1,13 @@ + package pidfile // import "github.com/docker/docker/pkg/pidfile" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" + ) + + func TestNewAndRemove(t *testing.T) { +- dir, err := ioutil.TempDir(os.TempDir(), "test-pidfile") ++ dir, err := os.MkdirTemp(os.TempDir(), "test-pidfile") + if err != nil { + t.Fatal("Could not create test directory") + } +diff --git a/pkg/plugins/client.go b/pkg/plugins/client.go +index 0353305358..752fecd0ae 100644 +--- a/pkg/plugins/client.go ++++ b/pkg/plugins/client.go +@@ -5,7 +5,6 @@ import ( + "context" + "encoding/json" + "io" +- "io/ioutil" + "net/http" + "net/url" + "time" +@@ -187,7 +186,7 @@ func (c *Client) callWithRetry(serviceMethod string, data io.Reader, retry bool, + } + + if resp.StatusCode != http.StatusOK { +- b, err := ioutil.ReadAll(resp.Body) ++ b, err := io.ReadAll(resp.Body) + resp.Body.Close() + cancelRequest() + if err != nil { +diff --git a/pkg/plugins/discovery.go b/pkg/plugins/discovery.go +index 4b79bd29ad..9d972b3c21 100644 +--- a/pkg/plugins/discovery.go ++++ b/pkg/plugins/discovery.go +@@ -3,7 +3,7 @@ package plugins // import "github.com/docker/docker/pkg/plugins" + import ( + "encoding/json" + "fmt" +- "io/ioutil" ++ "io/fs" + "net/url" + "os" + "path/filepath" +@@ -29,33 +29,35 @@ func newLocalRegistry() localRegistry { + // Scan scans all the plugin paths and returns all the names it found + func Scan() ([]string, error) { + var names []string +- dirEntries, err := ioutil.ReadDir(socketsPath) ++ dirEntries, err := os.ReadDir(socketsPath) + if err != nil && !os.IsNotExist(err) { + return nil, errors.Wrap(err, "error reading dir entries") + } + +- for _, fi := range dirEntries { +- if fi.IsDir() { +- fi, err = os.Stat(filepath.Join(socketsPath, fi.Name(), fi.Name()+".sock")) ++ for _, entry := range dirEntries { ++ if entry.IsDir() { ++ fi, err := os.Stat(filepath.Join(socketsPath, entry.Name(), entry.Name()+".sock")) + if err != nil { + continue + } ++ ++ entry = fs.FileInfoToDirEntry(fi) + } + +- if fi.Mode()&os.ModeSocket != 0 { +- names = append(names, strings.TrimSuffix(filepath.Base(fi.Name()), filepath.Ext(fi.Name()))) ++ if entry.Type()&os.ModeSocket != 0 { ++ names = append(names, strings.TrimSuffix(filepath.Base(entry.Name()), filepath.Ext(entry.Name()))) + } + } + + for _, p := range specsPaths { +- dirEntries, err := ioutil.ReadDir(p) ++ dirEntries, err := os.ReadDir(p) + if err != nil && !os.IsNotExist(err) { + return nil, errors.Wrap(err, "error reading dir entries") + } + + for _, fi := range dirEntries { + if fi.IsDir() { +- infos, err := ioutil.ReadDir(filepath.Join(p, fi.Name())) ++ infos, err := os.ReadDir(filepath.Join(p, fi.Name())) + if err != nil { + continue + } +@@ -108,7 +110,7 @@ func (l *localRegistry) Plugin(name string) (*Plugin, error) { + } + + func readPluginInfo(name, path string) (*Plugin, error) { +- content, err := ioutil.ReadFile(path) ++ content, err := os.ReadFile(path) + if err != nil { + return nil, err + } +diff --git a/pkg/plugins/discovery_test.go b/pkg/plugins/discovery_test.go +index 28fda41bad..f162fe662a 100644 +--- a/pkg/plugins/discovery_test.go ++++ b/pkg/plugins/discovery_test.go +@@ -1,14 +1,13 @@ + package plugins // import "github.com/docker/docker/pkg/plugins" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" + ) + + func Setup(t *testing.T) (string, func()) { +- tmpdir, err := ioutil.TempDir("", "docker-test") ++ tmpdir, err := os.MkdirTemp("", "docker-test") + if err != nil { + t.Fatal(err) + } +@@ -44,7 +43,7 @@ func TestFileSpecPlugin(t *testing.T) { + if err := os.MkdirAll(filepath.Dir(c.path), 0755); err != nil { + t.Fatal(err) + } +- if err := ioutil.WriteFile(c.path, []byte(c.addr), 0644); err != nil { ++ if err := os.WriteFile(c.path, []byte(c.addr), 0644); err != nil { + t.Fatal(err) + } + +@@ -87,7 +86,7 @@ func TestFileJSONSpecPlugin(t *testing.T) { + } + }` + +- if err := ioutil.WriteFile(p, []byte(spec), 0644); err != nil { ++ if err := os.WriteFile(p, []byte(spec), 0644); err != nil { + t.Fatal(err) + } + +@@ -128,7 +127,7 @@ func TestFileJSONSpecPluginWithoutTLSConfig(t *testing.T) { + "Addr": "https://example.com/docker/plugin" + }` + +- if err := ioutil.WriteFile(p, []byte(spec), 0644); err != nil { ++ if err := os.WriteFile(p, []byte(spec), 0644); err != nil { + t.Fatal(err) + } + +diff --git a/pkg/plugins/discovery_unix_test.go b/pkg/plugins/discovery_unix_test.go +index 99e2fe3203..cb1f204f91 100644 +--- a/pkg/plugins/discovery_unix_test.go ++++ b/pkg/plugins/discovery_unix_test.go +@@ -5,7 +5,6 @@ package plugins // import "github.com/docker/docker/pkg/plugins" + + import ( + "fmt" +- "io/ioutil" + "net" + "os" + "path/filepath" +@@ -85,7 +84,7 @@ func TestScan(t *testing.T) { + t.Fatal(err) + } + +- err = ioutil.WriteFile(path, []byte(addr), 0644) ++ err = os.WriteFile(path, []byte(addr), 0644) + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/plugins/plugin_test.go b/pkg/plugins/plugin_test.go +index 7c7f745d29..1252dd17b2 100644 +--- a/pkg/plugins/plugin_test.go ++++ b/pkg/plugins/plugin_test.go +@@ -4,8 +4,8 @@ import ( + "bytes" + "encoding/json" + "io" +- "io/ioutil" + "net/http" ++ "os" + "path/filepath" + "runtime" + "sync" +@@ -132,7 +132,7 @@ func TestGetAll(t *testing.T) { + "Addr": "https://example.com/docker/plugin" + }` + +- if err := ioutil.WriteFile(p, []byte(spec), 0644); err != nil { ++ if err := os.WriteFile(p, []byte(spec), 0644); err != nil { + t.Fatal(err) + } + +diff --git a/pkg/plugins/pluginrpc-gen/main.go b/pkg/plugins/pluginrpc-gen/main.go +index e77a7d45ff..cd39588340 100644 +--- a/pkg/plugins/pluginrpc-gen/main.go ++++ b/pkg/plugins/pluginrpc-gen/main.go +@@ -5,7 +5,6 @@ import ( + "flag" + "fmt" + "go/format" +- "io/ioutil" + "os" + "unicode" + "unicode/utf8" +@@ -79,7 +78,7 @@ func main() { + errorOut("parser error", generatedTempl.Execute(&buf, analysis)) + src, err := format.Source(buf.Bytes()) + errorOut("error formatting generated source:\n"+buf.String(), err) +- errorOut("error writing file", ioutil.WriteFile(*outputFile, src, 0644)) ++ errorOut("error writing file", os.WriteFile(*outputFile, src, 0644)) + } + + func toLower(s string) string { +diff --git a/pkg/progress/progressreader_test.go b/pkg/progress/progressreader_test.go +index e7081cc1f4..0aaf398ed0 100644 +--- a/pkg/progress/progressreader_test.go ++++ b/pkg/progress/progressreader_test.go +@@ -3,13 +3,12 @@ package progress // import "github.com/docker/docker/pkg/progress" + import ( + "bytes" + "io" +- "io/ioutil" + "testing" + ) + + func TestOutputOnPrematureClose(t *testing.T) { + content := []byte("TESTING") +- reader := ioutil.NopCloser(bytes.NewReader(content)) ++ reader := io.NopCloser(bytes.NewReader(content)) + progressChan := make(chan Progress, 10) + + pr := NewProgressReader(reader, ChanOutput(progressChan), int64(len(content)), "Test", "Read") +@@ -41,12 +40,12 @@ drainLoop: + + func TestCompleteSilently(t *testing.T) { + content := []byte("TESTING") +- reader := ioutil.NopCloser(bytes.NewReader(content)) ++ reader := io.NopCloser(bytes.NewReader(content)) + progressChan := make(chan Progress, 10) + + pr := NewProgressReader(reader, ChanOutput(progressChan), int64(len(content)), "Test", "Read") + +- out, err := ioutil.ReadAll(pr) ++ out, err := io.ReadAll(pr) + if err != nil { + pr.Close() + t.Fatal(err) +diff --git a/pkg/signal/trap_linux_test.go b/pkg/signal/trap_linux_test.go +index b2b1c8c024..89882ba91b 100644 +--- a/pkg/signal/trap_linux_test.go ++++ b/pkg/signal/trap_linux_test.go +@@ -4,7 +4,6 @@ + package signal // import "github.com/docker/docker/pkg/signal" + + import ( +- "io/ioutil" + "os" + "os/exec" + "syscall" +@@ -16,7 +15,7 @@ import ( + + func buildTestBinary(t *testing.T, tmpdir string, prefix string) (string, string) { + t.Helper() +- tmpDir, err := ioutil.TempDir(tmpdir, prefix) ++ tmpDir, err := os.MkdirTemp(tmpdir, prefix) + assert.NilError(t, err) + exePath := tmpDir + "/" + prefix + wd, _ := os.Getwd() +@@ -67,12 +66,12 @@ func TestTrap(t *testing.T) { + } + + func TestDumpStacks(t *testing.T) { +- directory, err := ioutil.TempDir("", "test-dump-tasks") ++ directory, err := os.MkdirTemp("", "test-dump-tasks") + assert.Check(t, err) + defer os.RemoveAll(directory) + dumpPath, err := DumpStacks(directory) + assert.Check(t, err) +- readFile, _ := ioutil.ReadFile(dumpPath) ++ readFile, _ := os.ReadFile(dumpPath) + fileData := string(readFile) + assert.Check(t, is.Contains(fileData, "goroutine")) + } +diff --git a/pkg/stdcopy/stdcopy_test.go b/pkg/stdcopy/stdcopy_test.go +index 63edb855e5..1fe8e83fdf 100644 +--- a/pkg/stdcopy/stdcopy_test.go ++++ b/pkg/stdcopy/stdcopy_test.go +@@ -4,13 +4,12 @@ import ( + "bytes" + "errors" + "io" +- "io/ioutil" + "strings" + "testing" + ) + + func TestNewStdWriter(t *testing.T) { +- writer := NewStdWriter(ioutil.Discard, Stdout) ++ writer := NewStdWriter(io.Discard, Stdout) + if writer == nil { + t.Fatalf("NewStdWriter with an invalid StdType should not return nil.") + } +@@ -28,7 +27,7 @@ func TestWriteWithUninitializedStdWriter(t *testing.T) { + } + + func TestWriteWithNilBytes(t *testing.T) { +- writer := NewStdWriter(ioutil.Discard, Stdout) ++ writer := NewStdWriter(io.Discard, Stdout) + n, err := writer.Write(nil) + if err != nil { + t.Fatalf("Shouldn't have fail when given no data") +@@ -39,7 +38,7 @@ func TestWriteWithNilBytes(t *testing.T) { + } + + func TestWrite(t *testing.T) { +- writer := NewStdWriter(ioutil.Discard, Stdout) ++ writer := NewStdWriter(io.Discard, Stdout) + data := []byte("Test StdWrite.Write") + n, err := writer.Write(data) + if err != nil { +@@ -104,7 +103,7 @@ func TestStdCopyWriteAndRead(t *testing.T) { + if err != nil { + t.Fatal(err) + } +- written, err := StdCopy(ioutil.Discard, ioutil.Discard, buffer) ++ written, err := StdCopy(io.Discard, io.Discard, buffer) + if err != nil { + t.Fatal(err) + } +@@ -134,7 +133,7 @@ func TestStdCopyReturnsErrorReadingHeader(t *testing.T) { + expectedError := errors.New("error") + reader := &customReader{ + err: expectedError} +- written, err := StdCopy(ioutil.Discard, ioutil.Discard, reader) ++ written, err := StdCopy(io.Discard, io.Discard, reader) + if written != 0 { + t.Fatalf("Expected 0 bytes read, got %d", written) + } +@@ -156,7 +155,7 @@ func TestStdCopyReturnsErrorReadingFrame(t *testing.T) { + n: stdWriterPrefixLen + 1, + err: expectedError, + src: buffer} +- written, err := StdCopy(ioutil.Discard, ioutil.Discard, reader) ++ written, err := StdCopy(io.Discard, io.Discard, reader) + if written != 0 { + t.Fatalf("Expected 0 bytes read, got %d", written) + } +@@ -177,7 +176,7 @@ func TestStdCopyDetectsCorruptedFrame(t *testing.T) { + n: stdWriterPrefixLen + 1, + err: io.EOF, + src: buffer} +- written, err := StdCopy(ioutil.Discard, ioutil.Discard, reader) ++ written, err := StdCopy(io.Discard, io.Discard, reader) + if written != startingBufLen { + t.Fatalf("Expected %d bytes read, got %d", startingBufLen, written) + } +@@ -187,8 +186,8 @@ func TestStdCopyDetectsCorruptedFrame(t *testing.T) { + } + + func TestStdCopyWithInvalidInputHeader(t *testing.T) { +- dstOut := NewStdWriter(ioutil.Discard, Stdout) +- dstErr := NewStdWriter(ioutil.Discard, Stderr) ++ dstOut := NewStdWriter(io.Discard, Stdout) ++ dstErr := NewStdWriter(io.Discard, Stderr) + src := strings.NewReader("Invalid input") + _, err := StdCopy(dstOut, dstErr, src) + if err == nil { +@@ -219,7 +218,7 @@ func TestStdCopyReturnsWriteErrors(t *testing.T) { + + dstOut := &errWriter{err: expectedError} + +- written, err := StdCopy(dstOut, ioutil.Discard, buffer) ++ written, err := StdCopy(dstOut, io.Discard, buffer) + if written != 0 { + t.Fatalf("StdCopy should have written 0, but has written %d", written) + } +@@ -237,7 +236,7 @@ func TestStdCopyDetectsNotFullyWrittenFrames(t *testing.T) { + } + dstOut := &errWriter{n: startingBufLen - 10} + +- written, err := StdCopy(dstOut, ioutil.Discard, buffer) ++ written, err := StdCopy(dstOut, io.Discard, buffer) + if written != 0 { + t.Fatalf("StdCopy should have return 0 written bytes, but returned %d", written) + } +@@ -266,7 +265,7 @@ func TestStdCopyReturnsErrorFromSystem(t *testing.T) { + + // now copy and demux. we should expect an error containing the string we + // wrote out +- _, err = StdCopy(ioutil.Discard, ioutil.Discard, buffer) ++ _, err = StdCopy(io.Discard, io.Discard, buffer) + if err == nil { + t.Fatal("expected error, got none") + } +@@ -276,7 +275,7 @@ func TestStdCopyReturnsErrorFromSystem(t *testing.T) { + } + + func BenchmarkWrite(b *testing.B) { +- w := NewStdWriter(ioutil.Discard, Stdout) ++ w := NewStdWriter(io.Discard, Stdout) + data := []byte("Test line for testing stdwriter performance\n") + data = bytes.Repeat(data, 100) + b.SetBytes(int64(len(data))) +diff --git a/pkg/sysinfo/cgroup2_linux.go b/pkg/sysinfo/cgroup2_linux.go +index 432356b498..72658f0545 100644 +--- a/pkg/sysinfo/cgroup2_linux.go ++++ b/pkg/sysinfo/cgroup2_linux.go +@@ -1,7 +1,6 @@ + package sysinfo // import "github.com/docker/docker/pkg/sysinfo" + + import ( +- "io/ioutil" + "os" + "path" + "strings" +@@ -139,13 +138,13 @@ func applyCPUSetCgroupInfoV2(info *SysInfo, controllers map[string]struct{}, dir + } + info.Cpuset = true + +- cpus, err := ioutil.ReadFile(path.Join(dirPath, "cpuset.cpus.effective")) ++ cpus, err := os.ReadFile(path.Join(dirPath, "cpuset.cpus.effective")) + if err != nil { + return warnings + } + info.Cpus = strings.TrimSpace(string(cpus)) + +- mems, err := ioutil.ReadFile(path.Join(dirPath, "cpuset.mems.effective")) ++ mems, err := os.ReadFile(path.Join(dirPath, "cpuset.mems.effective")) + if err != nil { + return warnings + } +diff --git a/pkg/sysinfo/sysinfo_linux.go b/pkg/sysinfo/sysinfo_linux.go +index 42709a4d35..e6b7ac787a 100644 +--- a/pkg/sysinfo/sysinfo_linux.go ++++ b/pkg/sysinfo/sysinfo_linux.go +@@ -2,7 +2,6 @@ package sysinfo // import "github.com/docker/docker/pkg/sysinfo" + + import ( + "fmt" +- "io/ioutil" + "os" + "path" + "strings" +@@ -215,13 +214,13 @@ func applyCPUSetCgroupInfo(info *SysInfo, cgMounts map[string]string) []string { + + var err error + +- cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus")) ++ cpus, err := os.ReadFile(path.Join(mountPoint, "cpuset.cpus")) + if err != nil { + return warnings + } + info.Cpus = strings.TrimSpace(string(cpus)) + +- mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems")) ++ mems, err := os.ReadFile(path.Join(mountPoint, "cpuset.mems")) + if err != nil { + return warnings + } +@@ -263,7 +262,7 @@ func applyNetworkingInfo(info *SysInfo, _ map[string]string) []string { + func applyAppArmorInfo(info *SysInfo, _ map[string]string) []string { + var warnings []string + if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) { +- if _, err := ioutil.ReadFile("/sys/kernel/security/apparmor/profiles"); err == nil { ++ if _, err := os.ReadFile("/sys/kernel/security/apparmor/profiles"); err == nil { + info.AppArmor = true + } + } +@@ -306,7 +305,7 @@ func cgroupEnabled(mountPoint, name string) bool { + } + + func readProcBool(path string) bool { +- val, err := ioutil.ReadFile(path) ++ val, err := os.ReadFile(path) + if err != nil { + return false + } +diff --git a/pkg/sysinfo/sysinfo_linux_test.go b/pkg/sysinfo/sysinfo_linux_test.go +index aa557c9230..06dbf442a8 100644 +--- a/pkg/sysinfo/sysinfo_linux_test.go ++++ b/pkg/sysinfo/sysinfo_linux_test.go +@@ -1,7 +1,6 @@ + package sysinfo // import "github.com/docker/docker/pkg/sysinfo" + + import ( +- "io/ioutil" + "os" + "path" + "path/filepath" +@@ -12,19 +11,19 @@ import ( + ) + + func TestReadProcBool(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "test-sysinfo-proc") ++ tmpDir, err := os.MkdirTemp("", "test-sysinfo-proc") + assert.NilError(t, err) + defer os.RemoveAll(tmpDir) + + procFile := filepath.Join(tmpDir, "read-proc-bool") +- err = ioutil.WriteFile(procFile, []byte("1"), 0644) ++ err = os.WriteFile(procFile, []byte("1"), 0644) + assert.NilError(t, err) + + if !readProcBool(procFile) { + t.Fatal("expected proc bool to be true, got false") + } + +- if err := ioutil.WriteFile(procFile, []byte("0"), 0644); err != nil { ++ if err := os.WriteFile(procFile, []byte("0"), 0644); err != nil { + t.Fatal(err) + } + if readProcBool(procFile) { +@@ -38,7 +37,7 @@ func TestReadProcBool(t *testing.T) { + } + + func TestCgroupEnabled(t *testing.T) { +- cgroupDir, err := ioutil.TempDir("", "cgroup-test") ++ cgroupDir, err := os.MkdirTemp("", "cgroup-test") + assert.NilError(t, err) + defer os.RemoveAll(cgroupDir) + +@@ -46,7 +45,7 @@ func TestCgroupEnabled(t *testing.T) { + t.Fatal("cgroupEnabled should be false") + } + +- err = ioutil.WriteFile(path.Join(cgroupDir, "test"), []byte{}, 0644) ++ err = os.WriteFile(path.Join(cgroupDir, "test"), []byte{}, 0644) + assert.NilError(t, err) + + if !cgroupEnabled(cgroupDir, "test") { +diff --git a/pkg/system/chtimes_test.go b/pkg/system/chtimes_test.go +index 5a3f98e199..3bb1fb2a60 100644 +--- a/pkg/system/chtimes_test.go ++++ b/pkg/system/chtimes_test.go +@@ -1,7 +1,6 @@ + package system // import "github.com/docker/docker/pkg/system" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -10,13 +9,13 @@ import ( + + // prepareTempFile creates a temporary file in a temporary directory. + func prepareTempFile(t *testing.T) (string, string) { +- dir, err := ioutil.TempDir("", "docker-system-test") ++ dir, err := os.MkdirTemp("", "docker-system-test") + if err != nil { + t.Fatal(err) + } + + file := filepath.Join(dir, "exist") +- if err := ioutil.WriteFile(file, []byte("hello"), 0644); err != nil { ++ if err := os.WriteFile(file, []byte("hello"), 0644); err != nil { + t.Fatal(err) + } + return file, dir +diff --git a/pkg/system/filesys_unix.go b/pkg/system/filesys_unix.go +index 186d9d9a11..8b991201a9 100644 +--- a/pkg/system/filesys_unix.go ++++ b/pkg/system/filesys_unix.go +@@ -4,7 +4,6 @@ + package system // import "github.com/docker/docker/pkg/system" + + import ( +- "io/ioutil" + "os" + "path/filepath" + ) +@@ -64,5 +63,5 @@ func OpenFileSequential(name string, flag int, perm os.FileMode) (*os.File, erro + // to find the pathname of the file. It is the caller's responsibility + // to remove the file when no longer needed. + func TempFileSequential(dir, prefix string) (f *os.File, err error) { +- return ioutil.TempFile(dir, prefix) ++ return os.CreateTemp(dir, prefix) + } +diff --git a/pkg/system/filesys_windows.go b/pkg/system/filesys_windows.go +index b4646277ab..8f79dc8fe0 100644 +--- a/pkg/system/filesys_windows.go ++++ b/pkg/system/filesys_windows.go +@@ -258,7 +258,7 @@ func nextSuffix() string { + return strconv.Itoa(int(1e9 + r%1e9))[1:] + } + +-// TempFileSequential is a copy of ioutil.TempFile, modified to use sequential ++// TempFileSequential is a copy of os.CreateTemp, modified to use sequential + // file access. Below is the original comment from golang: + // TempFile creates a new temporary file in the directory dir + // with a name beginning with prefix, opens the file for reading +diff --git a/pkg/system/process_unix.go b/pkg/system/process_unix.go +index 145689b88a..d2ab9c3d7e 100644 +--- a/pkg/system/process_unix.go ++++ b/pkg/system/process_unix.go +@@ -5,7 +5,7 @@ package system // import "github.com/docker/docker/pkg/system" + + import ( + "fmt" +- "io/ioutil" ++ "os" + "strings" + "syscall" + +@@ -31,7 +31,7 @@ func KillProcess(pid int) { + // http://man7.org/linux/man-pages/man5/proc.5.html + func IsProcessZombie(pid int) (bool, error) { + statPath := fmt.Sprintf("/proc/%d/stat", pid) +- dataBytes, err := ioutil.ReadFile(statPath) ++ dataBytes, err := os.ReadFile(statPath) + if err != nil { + return false, err + } +diff --git a/pkg/system/rm_nodarwin_test.go b/pkg/system/rm_nodarwin_test.go +index 9047f1ecad..f29137ca87 100644 +--- a/pkg/system/rm_nodarwin_test.go ++++ b/pkg/system/rm_nodarwin_test.go +@@ -4,7 +4,7 @@ + package system // import "github.com/docker/docker/pkg/system" + + import ( +- "io/ioutil" ++ "os" + "testing" + ) + +@@ -16,7 +16,7 @@ func TestEnsureRemoveAllNotExist(t *testing.T) { + } + + func TestEnsureRemoveAllWithDir(t *testing.T) { +- dir, err := ioutil.TempDir("", "test-ensure-removeall-with-dir") ++ dir, err := os.MkdirTemp("", "test-ensure-removeall-with-dir") + if err != nil { + t.Fatal(err) + } +@@ -26,7 +26,7 @@ func TestEnsureRemoveAllWithDir(t *testing.T) { + } + + func TestEnsureRemoveAllWithFile(t *testing.T) { +- tmp, err := ioutil.TempFile("", "test-ensure-removeall-with-dir") ++ tmp, err := os.CreateTemp("", "test-ensure-removeall-with-dir") + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/system/rm_test.go b/pkg/system/rm_test.go +index 9db1f64b1e..f3d0390e39 100644 +--- a/pkg/system/rm_test.go ++++ b/pkg/system/rm_test.go +@@ -4,7 +4,6 @@ + package system // import "github.com/docker/docker/pkg/system" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -17,11 +16,11 @@ import ( + func TestEnsureRemoveAllWithMount(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") + +- dir1, err := ioutil.TempDir("", "test-ensure-removeall-with-dir1") ++ dir1, err := os.MkdirTemp("", "test-ensure-removeall-with-dir1") + if err != nil { + t.Fatal(err) + } +- dir2, err := ioutil.TempDir("", "test-ensure-removeall-with-dir2") ++ dir2, err := os.MkdirTemp("", "test-ensure-removeall-with-dir2") + if err != nil { + t.Fatal(err) + } +diff --git a/pkg/system/utimes_unix_test.go b/pkg/system/utimes_unix_test.go +index dd85c94466..30482b7c07 100644 +--- a/pkg/system/utimes_unix_test.go ++++ b/pkg/system/utimes_unix_test.go +@@ -4,7 +4,6 @@ + package system // import "github.com/docker/docker/pkg/system" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "syscall" +@@ -13,13 +12,13 @@ import ( + + // prepareFiles creates files for testing in the temp directory + func prepareFiles(t *testing.T) (string, string, string, string) { +- dir, err := ioutil.TempDir("", "docker-system-test") ++ dir, err := os.MkdirTemp("", "docker-system-test") + if err != nil { + t.Fatal(err) + } + + file := filepath.Join(dir, "exist") +- if err := ioutil.WriteFile(file, []byte("hello"), 0644); err != nil { ++ if err := os.WriteFile(file, []byte("hello"), 0644); err != nil { + t.Fatal(err) + } + +diff --git a/pkg/tailfile/tailfile_test.go b/pkg/tailfile/tailfile_test.go +index 9e4d2be3ac..15c8acfe01 100644 +--- a/pkg/tailfile/tailfile_test.go ++++ b/pkg/tailfile/tailfile_test.go +@@ -6,7 +6,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "os" + "strings" + "testing" +@@ -15,7 +14,7 @@ import ( + ) + + func TestTailFile(t *testing.T) { +- f, err := ioutil.TempFile("", "tail-test") ++ f, err := os.CreateTemp("", "tail-test") + if err != nil { + t.Fatal(err) + } +@@ -69,7 +68,7 @@ truncated line`) + } + + func TestTailFileManyLines(t *testing.T) { +- f, err := ioutil.TempFile("", "tail-test") ++ f, err := os.CreateTemp("", "tail-test") + if err != nil { + t.Fatal(err) + } +@@ -100,7 +99,7 @@ truncated line`) + } + + func TestTailEmptyFile(t *testing.T) { +- f, err := ioutil.TempFile("", "tail-test") ++ f, err := os.CreateTemp("", "tail-test") + if err != nil { + t.Fatal(err) + } +@@ -116,7 +115,7 @@ func TestTailEmptyFile(t *testing.T) { + } + + func TestTailNegativeN(t *testing.T) { +- f, err := ioutil.TempFile("", "tail-test") ++ f, err := os.CreateTemp("", "tail-test") + if err != nil { + t.Fatal(err) + } +@@ -140,7 +139,7 @@ truncated line`) + } + + func BenchmarkTail(b *testing.B) { +- f, err := ioutil.TempFile("", "tail-test") ++ f, err := os.CreateTemp("", "tail-test") + if err != nil { + b.Fatal(err) + } +@@ -235,7 +234,7 @@ func TestNewTailReader(t *testing.T) { + assert.NilError(t, err) + assert.Check(t, lines == i, "%d -- %d", lines, i) + +- b, err := ioutil.ReadAll(tr) ++ b, err := io.ReadAll(tr) + assert.NilError(t, err) + + expectLines := test.data[len(test.data)-i:] +@@ -262,7 +261,7 @@ func TestNewTailReader(t *testing.T) { + + assert.NilError(t, err) + assert.Check(t, lines == len(test.data), "%d -- %d", lines, len(test.data)) +- b, err := ioutil.ReadAll(tr) ++ b, err := io.ReadAll(tr) + assert.NilError(t, err) + assert.Check(t, bytes.Equal(b, []byte(s)), "\n%v\n%v", b, []byte(s)) + }) +diff --git a/pkg/tarsum/builder_context_test.go b/pkg/tarsum/builder_context_test.go +index 86adb442d6..0d69d3127b 100644 +--- a/pkg/tarsum/builder_context_test.go ++++ b/pkg/tarsum/builder_context_test.go +@@ -2,7 +2,6 @@ package tarsum // import "github.com/docker/docker/pkg/tarsum" + + import ( + "io" +- "io/ioutil" + "os" + "testing" + ) +@@ -22,7 +21,7 @@ func TestTarSumRemoveNonExistent(t *testing.T) { + } + + // Read and discard bytes so that it populates sums +- _, err = io.Copy(ioutil.Discard, ts) ++ _, err = io.Copy(io.Discard, ts) + if err != nil { + t.Errorf("failed to read from %s: %s", filename, err) + } +@@ -52,7 +51,7 @@ func TestTarSumRemove(t *testing.T) { + } + + // Read and discard bytes so that it populates sums +- _, err = io.Copy(ioutil.Discard, ts) ++ _, err = io.Copy(io.Discard, ts) + if err != nil { + t.Errorf("failed to read from %s: %s", filename, err) + } +diff --git a/pkg/tarsum/tarsum_test.go b/pkg/tarsum/tarsum_test.go +index 24f7cce7d4..1945f4a5cf 100644 +--- a/pkg/tarsum/tarsum_test.go ++++ b/pkg/tarsum/tarsum_test.go +@@ -12,7 +12,6 @@ import ( + "encoding/hex" + "fmt" + "io" +- "io/ioutil" + "os" + "strings" + "testing" +@@ -127,7 +126,7 @@ func sizedTar(opts sizedOptions) io.Reader { + err error + ) + if opts.realFile { +- fh, err = ioutil.TempFile("", "tarsum") ++ fh, err = os.CreateTemp("", "tarsum") + if err != nil { + return nil + } +@@ -366,7 +365,7 @@ func TestTarSums(t *testing.T) { + } + + // Read and discard remaining bytes +- _, err = io.Copy(ioutil.Discard, ts) ++ _, err = io.Copy(io.Discard, ts) + if err != nil { + t.Errorf("failed to copy from %s: %s", layer.filename, err) + continue +@@ -380,7 +379,7 @@ func TestTarSums(t *testing.T) { + } + defer jfh.Close() + +- buf, err := ioutil.ReadAll(jfh) ++ buf, err := io.ReadAll(jfh) + if err != nil { + t.Errorf("failed to readAll %s: %s", layer.jsonfile, err) + continue +@@ -545,7 +544,7 @@ func renderSumForHeader(v Version, h *tar.Header, data []byte) (string, error) { + if err != nil { + return "", err + } +- if _, err = io.Copy(ioutil.Discard, tr); err != nil { ++ if _, err = io.Copy(io.Discard, tr); err != nil { + return "", err + } + } +@@ -578,7 +577,7 @@ func Benchmark9kTar(b *testing.B) { + b.Error(err) + return + } +- io.Copy(ioutil.Discard, ts) ++ io.Copy(io.Discard, ts) + ts.Sum(nil) + } + } +@@ -609,7 +608,7 @@ func Benchmark9kTarGzip(b *testing.B) { + b.Error(err) + return + } +- io.Copy(ioutil.Discard, ts) ++ io.Copy(io.Discard, ts) + ts.Sum(nil) + } + } +@@ -651,7 +650,7 @@ func benchmarkTar(b *testing.B, opts sizedOptions, isGzip bool) { + b.Error(err) + return + } +- io.Copy(ioutil.Discard, ts) ++ io.Copy(io.Discard, ts) + ts.Sum(nil) + fh.Seek(0, 0) + } +diff --git a/plugin/backend_linux.go b/plugin/backend_linux.go +index 88ab8b38e7..834f5a8119 100644 +--- a/plugin/backend_linux.go ++++ b/plugin/backend_linux.go +@@ -7,7 +7,6 @@ import ( + "context" + "encoding/json" + "io" +- "io/ioutil" + "net/http" + "os" + "path" +@@ -225,7 +224,7 @@ func (pm *Manager) Upgrade(ctx context.Context, ref reference.Named, name string + pm.muGC.RLock() + defer pm.muGC.RUnlock() + +- tmpRootFSDir, err := ioutil.TempDir(pm.tmpDir(), ".rootfs") ++ tmpRootFSDir, err := os.MkdirTemp(pm.tmpDir(), ".rootfs") + if err != nil { + return errors.Wrap(err, "error creating tmp dir for plugin rootfs") + } +@@ -270,7 +269,7 @@ func (pm *Manager) Pull(ctx context.Context, ref reference.Named, name string, m + return errdefs.InvalidParameter(err) + } + +- tmpRootFSDir, err := ioutil.TempDir(pm.tmpDir(), ".rootfs") ++ tmpRootFSDir, err := os.MkdirTemp(pm.tmpDir(), ".rootfs") + if err != nil { + return errors.Wrap(errdefs.System(err), "error preparing upgrade") + } +@@ -633,7 +632,7 @@ func (pm *Manager) CreateFromContext(ctx context.Context, tarCtx io.ReadCloser, + return err + } + +- tmpRootFSDir, err := ioutil.TempDir(pm.tmpDir(), ".rootfs") ++ tmpRootFSDir, err := os.MkdirTemp(pm.tmpDir(), ".rootfs") + if err != nil { + return errors.Wrap(err, "failed to create temp directory") + } +@@ -766,7 +765,7 @@ func splitConfigRootFSFromTar(in io.ReadCloser, config *[]byte) io.ReadCloser { + name = name[1:] + } + if name == configFileName { +- dt, err := ioutil.ReadAll(content) ++ dt, err := io.ReadAll(content) + if err != nil { + pw.CloseWithError(errors.Wrapf(err, "failed to read %s", configFileName)) + return +@@ -788,7 +787,7 @@ func splitConfigRootFSFromTar(in io.ReadCloser, config *[]byte) io.ReadCloser { + } + hasRootFS = true + } else { +- io.Copy(ioutil.Discard, content) ++ io.Copy(io.Discard, content) + } + } + }() +diff --git a/plugin/backend_linux_test.go b/plugin/backend_linux_test.go +index 81cf2ebb76..bb4e7172f5 100644 +--- a/plugin/backend_linux_test.go ++++ b/plugin/backend_linux_test.go +@@ -1,14 +1,13 @@ + package plugin // import "github.com/docker/docker/plugin" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" + ) + + func TestAtomicRemoveAllNormal(t *testing.T) { +- dir, err := ioutil.TempDir("", "atomic-remove-with-normal") ++ dir, err := os.MkdirTemp("", "atomic-remove-with-normal") + if err != nil { + t.Fatal(err) + } +@@ -27,7 +26,7 @@ func TestAtomicRemoveAllNormal(t *testing.T) { + } + + func TestAtomicRemoveAllAlreadyExists(t *testing.T) { +- dir, err := ioutil.TempDir("", "atomic-remove-already-exists") ++ dir, err := os.MkdirTemp("", "atomic-remove-already-exists") + if err != nil { + t.Fatal(err) + } +@@ -55,7 +54,7 @@ func TestAtomicRemoveAllNotExist(t *testing.T) { + t.Fatal(err) + } + +- dir, err := ioutil.TempDir("", "atomic-remove-already-exists") ++ dir, err := os.MkdirTemp("", "atomic-remove-already-exists") + if err != nil { + t.Fatal(err) + } +diff --git a/plugin/manager.go b/plugin/manager.go +index c237378fa3..cfc49f285e 100644 +--- a/plugin/manager.go ++++ b/plugin/manager.go +@@ -4,7 +4,6 @@ import ( + "context" + "encoding/json" + "io" +- "io/ioutil" + "os" + "path/filepath" + "reflect" +@@ -178,7 +177,7 @@ func handleLoadError(err error, id string) { + } + + func (pm *Manager) reload() error { // todo: restore +- dir, err := ioutil.ReadDir(pm.config.Root) ++ dir, err := os.ReadDir(pm.config.Root) + if err != nil { + return errors.Wrapf(err, "failed to read %v", pm.config.Root) + } +@@ -268,7 +267,7 @@ func (pm *Manager) Get(idOrName string) (*v2.Plugin, error) { + + func (pm *Manager) loadPlugin(id string) (*v2.Plugin, error) { + p := filepath.Join(pm.config.Root, id, configFileName) +- dt, err := ioutil.ReadFile(p) ++ dt, err := os.ReadFile(p) + if err != nil { + return nil, errors.Wrapf(err, "error reading %v", p) + } +diff --git a/plugin/manager_linux_test.go b/plugin/manager_linux_test.go +index 84c17f9f29..b9f71e3702 100644 +--- a/plugin/manager_linux_test.go ++++ b/plugin/manager_linux_test.go +@@ -2,7 +2,6 @@ package plugin // import "github.com/docker/docker/plugin" + + import ( + "io" +- "io/ioutil" + "net" + "os" + "path/filepath" +@@ -21,7 +20,7 @@ import ( + + func TestManagerWithPluginMounts(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") +- root, err := ioutil.TempDir("", "test-store-with-plugin-mounts") ++ root, err := os.MkdirTemp("", "test-store-with-plugin-mounts") + if err != nil { + t.Fatal(err) + } +@@ -107,7 +106,7 @@ func (e *simpleExecutor) Signal(id string, signal int) error { + } + + func TestCreateFailed(t *testing.T) { +- root, err := ioutil.TempDir("", "test-create-failed") ++ root, err := os.MkdirTemp("", "test-create-failed") + if err != nil { + t.Fatal(err) + } +@@ -178,7 +177,7 @@ func TestPluginAlreadyRunningOnStartup(t *testing.T) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") + t.Parallel() + +- root, err := ioutil.TempDir("", t.Name()) ++ root, err := os.MkdirTemp("", t.Name()) + if err != nil { + t.Fatal(err) + } +@@ -211,7 +210,7 @@ func TestPluginAlreadyRunningOnStartup(t *testing.T) { + p.PluginObj.Enabled = true + + // Need a short-ish path here so we don't run into unix socket path length issues. +- config.ExecRoot, err = ioutil.TempDir("", "plugintest") ++ config.ExecRoot, err = os.MkdirTemp("", "plugintest") + + executor := &executorWithRunning{root: config.ExecRoot} + config.CreateExecutor = func(m *Manager) (Executor, error) { executor.m = m; return executor, nil } +diff --git a/profiles/apparmor/apparmor.go b/profiles/apparmor/apparmor.go +index c2c805bdcc..b3566b2f73 100644 +--- a/profiles/apparmor/apparmor.go ++++ b/profiles/apparmor/apparmor.go +@@ -6,7 +6,6 @@ package apparmor // import "github.com/docker/docker/profiles/apparmor" + import ( + "bufio" + "io" +- "io/ioutil" + "os" + "path" + "strings" +@@ -74,7 +73,7 @@ func InstallDefault(name string) error { + } + + // Figure out the daemon profile. +- currentProfile, err := ioutil.ReadFile("/proc/self/attr/current") ++ currentProfile, err := os.ReadFile("/proc/self/attr/current") + if err != nil { + // If we couldn't get the daemon profile, assume we are running + // unconfined which is generally the default. +@@ -93,7 +92,7 @@ func InstallDefault(name string) error { + p.DaemonProfile = daemonProfile + + // Install to a temporary directory. +- f, err := ioutil.TempFile("", name) ++ f, err := os.CreateTemp("", name) + if err != nil { + return err + } +diff --git a/profiles/seccomp/generate.go b/profiles/seccomp/generate.go +index b978cee8f6..a5d56247ab 100644 +--- a/profiles/seccomp/generate.go ++++ b/profiles/seccomp/generate.go +@@ -5,7 +5,6 @@ package main + + import ( + "encoding/json" +- "io/ioutil" + "os" + "path/filepath" + +@@ -27,7 +26,7 @@ func main() { + panic(err) + } + +- if err := ioutil.WriteFile(f, b, 0644); err != nil { ++ if err := os.WriteFile(f, b, 0644); err != nil { + panic(err) + } + } +diff --git a/profiles/seccomp/seccomp_test.go b/profiles/seccomp/seccomp_test.go +index 15bba8b632..62e6e6a39d 100644 +--- a/profiles/seccomp/seccomp_test.go ++++ b/profiles/seccomp/seccomp_test.go +@@ -5,7 +5,7 @@ package seccomp // import "github.com/docker/docker/profiles/seccomp" + + import ( + "encoding/json" +- "io/ioutil" ++ "os" + "strings" + "testing" + +@@ -14,7 +14,7 @@ import ( + ) + + func TestLoadProfile(t *testing.T) { +- f, err := ioutil.ReadFile("fixtures/example.json") ++ f, err := os.ReadFile("fixtures/example.json") + if err != nil { + t.Fatal(err) + } +@@ -27,7 +27,7 @@ func TestLoadProfile(t *testing.T) { + // TestLoadLegacyProfile tests loading a seccomp profile in the old format + // (before https://github.com/docker/docker/pull/24510) + func TestLoadLegacyProfile(t *testing.T) { +- f, err := ioutil.ReadFile("fixtures/default-old-format.json") ++ f, err := os.ReadFile("fixtures/default-old-format.json") + if err != nil { + t.Fatal(err) + } +@@ -38,7 +38,7 @@ func TestLoadLegacyProfile(t *testing.T) { + } + + func TestLoadDefaultProfile(t *testing.T) { +- f, err := ioutil.ReadFile("default.json") ++ f, err := os.ReadFile("default.json") + if err != nil { + t.Fatal(err) + } +@@ -54,7 +54,7 @@ func TestUnmarshalDefaultProfile(t *testing.T) { + t.Skip("seccomp not supported") + } + +- f, err := ioutil.ReadFile("default.json") ++ f, err := os.ReadFile("default.json") + if err != nil { + t.Fatal(err) + } +@@ -122,7 +122,7 @@ func TestMarshalUnmarshalFilter(t *testing.T) { + } + + func TestLoadConditional(t *testing.T) { +- f, err := ioutil.ReadFile("fixtures/conditional_include.json") ++ f, err := os.ReadFile("fixtures/conditional_include.json") + if err != nil { + t.Fatal(err) + } +diff --git a/quota/projectquota.go b/quota/projectquota.go +index 19078ce1dc..1230fdb22c 100644 +--- a/quota/projectquota.go ++++ b/quota/projectquota.go +@@ -53,7 +53,7 @@ const int Q_XGETQSTAT_PRJQUOTA = QCMD(Q_XGETQSTAT, PRJQUOTA); + */ + import "C" + import ( +- "io/ioutil" ++ "os" + "path" + "path/filepath" + "sync" +@@ -337,7 +337,7 @@ func (q *Control) findNextProjectID(home string, baseID uint32) error { + return projid, nil + } + +- files, err := ioutil.ReadDir(home) ++ files, err := os.ReadDir(home) + if err != nil { + return errors.Errorf("read directory failed: %s", home) + } +@@ -353,7 +353,7 @@ func (q *Control) findNextProjectID(home string, baseID uint32) error { + if projid > 0 && projid != baseID { + continue + } +- subfiles, err := ioutil.ReadDir(path) ++ subfiles, err := os.ReadDir(path) + if err != nil { + return errors.Errorf("read directory failed: %s", path) + } +diff --git a/quota/projectquota_test.go b/quota/projectquota_test.go +index 0970cfe9b2..e25fe99fb4 100644 +--- a/quota/projectquota_test.go ++++ b/quota/projectquota_test.go +@@ -5,7 +5,6 @@ package quota // import "github.com/docker/docker/quota" + + import ( + "io" +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -51,7 +50,7 @@ func testBlockDevQuotaEnabled(t *testing.T, mountPoint, backingFsDev, testDir st + func testSmallerThanQuota(t *testing.T, ctrl *Control, homeDir, testDir, testSubDir string) { + assert.NilError(t, ctrl.SetQuota(testSubDir, Quota{testQuotaSize})) + smallerThanQuotaFile := filepath.Join(testSubDir, "smaller-than-quota") +- assert.NilError(t, ioutil.WriteFile(smallerThanQuotaFile, make([]byte, testQuotaSize/2), 0644)) ++ assert.NilError(t, os.WriteFile(smallerThanQuotaFile, make([]byte, testQuotaSize/2), 0644)) + assert.NilError(t, os.Remove(smallerThanQuotaFile)) + } + +@@ -62,7 +61,7 @@ func testBiggerThanQuota(t *testing.T, ctrl *Control, homeDir, testDir, testSubD + assert.NilError(t, ctrl.SetQuota(testSubDir, Quota{testQuotaSize})) + + biggerThanQuotaFile := filepath.Join(testSubDir, "bigger-than-quota") +- err := ioutil.WriteFile(biggerThanQuotaFile, make([]byte, testQuotaSize+1), 0644) ++ err := os.WriteFile(biggerThanQuotaFile, make([]byte, testQuotaSize+1), 0644) + assert.Assert(t, is.ErrorContains(err, "")) + if err == io.ErrShortWrite { + assert.NilError(t, os.Remove(biggerThanQuotaFile)) +diff --git a/quota/testhelpers.go b/quota/testhelpers.go +index 52ab2ce949..6087162e2a 100644 +--- a/quota/testhelpers.go ++++ b/quota/testhelpers.go +@@ -4,7 +4,6 @@ + package quota // import "github.com/docker/docker/quota" + + import ( +- "io/ioutil" + "os" + "os/exec" + "testing" +@@ -38,7 +37,7 @@ func PrepareQuotaTestImage(t *testing.T) (string, error) { + } + + // create a sparse image +- imageFile, err := ioutil.TempFile("", "xfs-image") ++ imageFile, err := os.CreateTemp("", "xfs-image") + if err != nil { + return "", err + } +@@ -101,7 +100,7 @@ func WrapMountTest(imageFileName string, enableQuota bool, testFunc func(t *test + backingFsDev, err := makeBackingFsDev(mountPoint) + assert.NilError(t, err) + +- testDir, err := ioutil.TempDir(mountPoint, "per-test") ++ testDir, err := os.MkdirTemp(mountPoint, "per-test") + assert.NilError(t, err) + defer os.RemoveAll(testDir) + +@@ -116,7 +115,7 @@ func WrapQuotaTest(testFunc func(t *testing.T, ctrl *Control, mountPoint, testDi + ctrl, err := NewControl(testDir) + assert.NilError(t, err) + +- testSubDir, err := ioutil.TempDir(testDir, "quota-test") ++ testSubDir, err := os.MkdirTemp(testDir, "quota-test") + assert.NilError(t, err) + testFunc(t, ctrl, mountPoint, testDir, testSubDir) + } +diff --git a/reference/store_test.go b/reference/store_test.go +index 66d19c8cb0..a2fdfdb75e 100644 +--- a/reference/store_test.go ++++ b/reference/store_test.go +@@ -2,7 +2,6 @@ package reference // import "github.com/docker/docker/reference" + + import ( + "bytes" +- "io/ioutil" + "os" + "path/filepath" + "strings" +@@ -29,7 +28,7 @@ var ( + ) + + func TestLoad(t *testing.T) { +- jsonFile, err := ioutil.TempFile("", "tag-store-test") ++ jsonFile, err := os.CreateTemp("", "tag-store-test") + if err != nil { + t.Fatalf("error creating temp file: %v", err) + } +@@ -63,7 +62,7 @@ func TestLoad(t *testing.T) { + } + + func TestSave(t *testing.T) { +- jsonFile, err := ioutil.TempFile("", "tag-store-test") ++ jsonFile, err := os.CreateTemp("", "tag-store-test") + assert.NilError(t, err) + + _, err = jsonFile.Write([]byte(`{}`)) +@@ -94,7 +93,7 @@ func TestSave(t *testing.T) { + } + } + +- jsonBytes, err := ioutil.ReadFile(jsonFile.Name()) ++ jsonBytes, err := os.ReadFile(jsonFile.Name()) + if err != nil { + t.Fatalf("could not read json file: %v", err) + } +@@ -105,7 +104,7 @@ func TestSave(t *testing.T) { + } + + func TestAddDeleteGet(t *testing.T) { +- jsonFile, err := ioutil.TempFile("", "tag-store-test") ++ jsonFile, err := os.CreateTemp("", "tag-store-test") + if err != nil { + t.Fatalf("error creating temp file: %v", err) + } +@@ -336,7 +335,7 @@ func TestAddDeleteGet(t *testing.T) { + } + + func TestInvalidTags(t *testing.T) { +- tmpDir, err := ioutil.TempDir("", "tag-store-test") ++ tmpDir, err := os.MkdirTemp("", "tag-store-test") + assert.NilError(t, err) + defer os.RemoveAll(tmpDir) + +diff --git a/registry/endpoint_v1.go b/registry/endpoint_v1.go +index a355a4f872..3b5ab2f5ff 100644 +--- a/registry/endpoint_v1.go ++++ b/registry/endpoint_v1.go +@@ -4,7 +4,7 @@ import ( + "crypto/tls" + "encoding/json" + "fmt" +- "io/ioutil" ++ "io" + "net/http" + "net/url" + "strings" +@@ -158,7 +158,7 @@ func (e *V1Endpoint) Ping() (PingResult, error) { + + defer resp.Body.Close() + +- jsonString, err := ioutil.ReadAll(resp.Body) ++ jsonString, err := io.ReadAll(resp.Body) + if err != nil { + return PingResult{Standalone: false}, fmt.Errorf("error while reading the http response: %s", err) + } +diff --git a/registry/registry.go b/registry/registry.go +index 7a70bf28b5..bcf2509f24 100644 +--- a/registry/registry.go ++++ b/registry/registry.go +@@ -5,7 +5,6 @@ import ( + "crypto/tls" + "errors" + "fmt" +- "io/ioutil" + "net" + "net/http" + "os" +@@ -54,7 +53,7 @@ func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) { + return tlsConfig, nil + } + +-func hasFile(files []os.FileInfo, name string) bool { ++func hasFile(files []os.DirEntry, name string) bool { + for _, f := range files { + if f.Name() == name { + return true +@@ -67,7 +66,7 @@ func hasFile(files []os.FileInfo, name string) bool { + // including roots and certificate pairs and updates the + // provided TLS configuration. + func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error { +- fs, err := ioutil.ReadDir(directory) ++ fs, err := os.ReadDir(directory) + if err != nil && !os.IsNotExist(err) { + return err + } +@@ -82,7 +81,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error { + tlsConfig.RootCAs = systemPool + } + logrus.Debugf("crt: %s", filepath.Join(directory, f.Name())) +- data, err := ioutil.ReadFile(filepath.Join(directory, f.Name())) ++ data, err := os.ReadFile(filepath.Join(directory, f.Name())) + if err != nil { + return err + } +diff --git a/registry/registry_mock_test.go b/registry/registry_mock_test.go +index 05e7c9c896..74c5a2b168 100644 +--- a/registry/registry_mock_test.go ++++ b/registry/registry_mock_test.go +@@ -5,7 +5,6 @@ import ( + "errors" + "fmt" + "io" +- "io/ioutil" + "net" + "net/http" + "net/http/httptest" +@@ -205,7 +204,7 @@ func writeResponse(w http.ResponseWriter, message interface{}, code int) { + } + + func readJSON(r *http.Request, dest interface{}) error { +- body, err := ioutil.ReadAll(r.Body) ++ body, err := io.ReadAll(r.Body) + if err != nil { + return err + } +@@ -327,7 +326,7 @@ func handlerPutImage(w http.ResponseWriter, r *http.Request) { + return + } + } +- body, err := ioutil.ReadAll(r.Body) ++ body, err := io.ReadAll(r.Body) + if err != nil { + apiError(w, fmt.Sprintf("Error: %s", err), http.StatusInternalServerError) + return +diff --git a/registry/resumable/resumablerequestreader_test.go b/registry/resumable/resumablerequestreader_test.go +index 786c6ab105..326307ff41 100644 +--- a/registry/resumable/resumablerequestreader_test.go ++++ b/registry/resumable/resumablerequestreader_test.go +@@ -3,7 +3,6 @@ package resumable // import "github.com/docker/docker/registry/resumable" + import ( + "fmt" + "io" +- "io/ioutil" + "net/http" + "net/http/httptest" + "strings" +@@ -134,7 +133,7 @@ func TestResumableRequestReaderWithEOFWith416Response(t *testing.T) { + StatusCode: http.StatusRequestedRangeNotSatisfiable, + ContentLength: 0, + Close: true, +- Body: ioutil.NopCloser(strings.NewReader("")), ++ Body: io.NopCloser(strings.NewReader("")), + } + + resreq := &requestReader{ +@@ -195,7 +194,7 @@ func TestResumableRequestReaderWithZeroTotalSize(t *testing.T) { + resreq := NewRequestReader(client, req, retries, 0) + defer resreq.Close() + +- data, err := ioutil.ReadAll(resreq) ++ data, err := io.ReadAll(resreq) + assert.NilError(t, err) + + resstr := strings.TrimSuffix(string(data), "\n") +@@ -221,7 +220,7 @@ func TestResumableRequestReader(t *testing.T) { + resreq := NewRequestReader(client, req, retries, imgSize) + defer resreq.Close() + +- data, err := ioutil.ReadAll(resreq) ++ data, err := io.ReadAll(resreq) + assert.NilError(t, err) + + resstr := strings.TrimSuffix(string(data), "\n") +@@ -250,7 +249,7 @@ func TestResumableRequestReaderWithInitialResponse(t *testing.T) { + resreq := NewRequestReaderWithInitialResponse(client, req, retries, imgSize, res) + defer resreq.Close() + +- data, err := ioutil.ReadAll(resreq) ++ data, err := io.ReadAll(resreq) + assert.NilError(t, err) + + resstr := strings.TrimSuffix(string(data), "\n") +diff --git a/rootless/specconv/specconv_linux.go b/rootless/specconv/specconv_linux.go +index 7cb9e2f6b3..9c84a7fe3b 100644 +--- a/rootless/specconv/specconv_linux.go ++++ b/rootless/specconv/specconv_linux.go +@@ -1,7 +1,7 @@ + package specconv // import "github.com/docker/docker/rootless/specconv" + + import ( +- "io/ioutil" ++ "os" + "strconv" + "strings" + +@@ -19,7 +19,7 @@ func ToRootless(spec *specs.Spec, v2Controllers []string) error { + } + + func getCurrentOOMScoreAdj() int { +- b, err := ioutil.ReadFile("/proc/self/oom_score_adj") ++ b, err := os.ReadFile("/proc/self/oom_score_adj") + if err != nil { + logrus.WithError(err).Warn("failed to read /proc/self/oom_score_adj") + return 0 +diff --git a/runconfig/config_test.go b/runconfig/config_test.go +index 8b316e66e7..01255ca5d0 100644 +--- a/runconfig/config_test.go ++++ b/runconfig/config_test.go +@@ -4,7 +4,7 @@ import ( + "bytes" + "encoding/json" + "fmt" +- "io/ioutil" ++ "os" + "runtime" + "strings" + "testing" +@@ -42,7 +42,7 @@ func TestDecodeContainerConfig(t *testing.T) { + } + + for _, f := range fixtures { +- b, err := ioutil.ReadFile(f.file) ++ b, err := os.ReadFile(f.file) + if err != nil { + t.Fatal(err) + } +diff --git a/runconfig/hostconfig_test.go b/runconfig/hostconfig_test.go +index 37219bbc4e..9039e07f12 100644 +--- a/runconfig/hostconfig_test.go ++++ b/runconfig/hostconfig_test.go +@@ -6,7 +6,7 @@ package runconfig // import "github.com/docker/docker/runconfig" + import ( + "bytes" + "fmt" +- "io/ioutil" ++ "os" + "testing" + + "github.com/docker/docker/api/types/container" +@@ -213,7 +213,7 @@ func TestDecodeHostConfig(t *testing.T) { + } + + for _, f := range fixtures { +- b, err := ioutil.ReadFile(f.file) ++ b, err := os.ReadFile(f.file) + if err != nil { + t.Fatal(err) + } +diff --git a/testutil/daemon/daemon.go b/testutil/daemon/daemon.go +index ebaad1cc7b..9c30554aba 100644 +--- a/testutil/daemon/daemon.go ++++ b/testutil/daemon/daemon.go +@@ -4,7 +4,6 @@ import ( + "context" + "encoding/json" + "fmt" +- "io/ioutil" + "net/http" + "os" + "os/exec" +@@ -253,7 +252,7 @@ func (d *Daemon) LogFileName() string { + + // ReadLogFile returns the content of the daemon log file + func (d *Daemon) ReadLogFile() ([]byte, error) { +- return ioutil.ReadFile(d.logFile.Name()) ++ return os.ReadFile(d.logFile.Name()) + } + + // NewClientT creates new client based on daemon's socket path +diff --git a/testutil/fakecontext/context.go b/testutil/fakecontext/context.go +index abd528df91..7ab37cfe0a 100644 +--- a/testutil/fakecontext/context.go ++++ b/testutil/fakecontext/context.go +@@ -3,7 +3,6 @@ package fakecontext // import "github.com/docker/docker/testutil/fakecontext" + import ( + "bytes" + "io" +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -31,7 +30,7 @@ func New(t testing.TB, dir string, modifiers ...func(*Fake) error) *Fake { + } + + func newDir(fake *Fake) error { +- tmp, err := ioutil.TempDir("", "fake-context") ++ tmp, err := os.MkdirTemp("", "fake-context") + if err != nil { + return err + } +@@ -96,7 +95,7 @@ func (f *Fake) addFile(file string, content []byte) error { + return err + } + } +- return ioutil.WriteFile(fp, content, 0644) ++ return os.WriteFile(fp, content, 0644) + + } + +diff --git a/testutil/fakegit/fakegit.go b/testutil/fakegit/fakegit.go +index e5375936b9..33594dc8a8 100644 +--- a/testutil/fakegit/fakegit.go ++++ b/testutil/fakegit/fakegit.go +@@ -2,7 +2,6 @@ package fakegit // import "github.com/docker/docker/testutil/fakegit" + + import ( + "fmt" +- "io/ioutil" + "net/http" + "net/http/httptest" + "os" +@@ -76,7 +75,7 @@ func New(c testing.TB, name string, files map[string]string, enforceLocalServer + c.Fatalf("error trying to commit to repo: %s (%s)", err, output) + } + +- root, err := ioutil.TempDir("", "docker-test-git-repo") ++ root, err := os.MkdirTemp("", "docker-test-git-repo") + if err != nil { + c.Fatal(err) + } +diff --git a/testutil/fakestorage/fixtures.go b/testutil/fakestorage/fixtures.go +index 1d9e3b6df3..e11bee3b28 100644 +--- a/testutil/fakestorage/fixtures.go ++++ b/testutil/fakestorage/fixtures.go +@@ -3,7 +3,6 @@ package fakestorage // import "github.com/docker/docker/testutil/fakestorage" + import ( + "context" + "io" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -30,7 +29,7 @@ func ensureHTTPServerImage(t testing.TB) { + + defer testEnv.ProtectImage(t, "httpserver:latest") + +- tmp, err := ioutil.TempDir("", "docker-http-server-test") ++ tmp, err := os.MkdirTemp("", "docker-http-server-test") + if err != nil { + t.Fatalf("could not build http server: %v", err) + } +@@ -85,6 +84,6 @@ func ensureHTTPServerImage(t testing.TB) { + Tags: []string{"httpserver"}, + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + assert.NilError(t, err) + } +diff --git a/testutil/fakestorage/storage.go b/testutil/fakestorage/storage.go +index 85ff858c72..8bcf1d8863 100644 +--- a/testutil/fakestorage/storage.go ++++ b/testutil/fakestorage/storage.go +@@ -4,7 +4,6 @@ import ( + "context" + "fmt" + "io" +- "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" +@@ -149,7 +148,7 @@ COPY . /static`); err != nil { + Tags: []string{image}, + }) + assert.NilError(t, err) +- _, err = io.Copy(ioutil.Discard, resp.Body) ++ _, err = io.Copy(io.Discard, resp.Body) + assert.NilError(t, err) + + // Start the container +diff --git a/testutil/fixtures/plugin/plugin.go b/testutil/fixtures/plugin/plugin.go +index 4a89a6c4e9..81ebc41b64 100644 +--- a/testutil/fixtures/plugin/plugin.go ++++ b/testutil/fixtures/plugin/plugin.go +@@ -4,7 +4,6 @@ import ( + "context" + "encoding/json" + "io" +- "io/ioutil" + "os" + "os/exec" + "path/filepath" +@@ -53,7 +52,7 @@ type CreateClient interface { + + // Create creates a new plugin with the specified name + func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error { +- tmpDir, err := ioutil.TempDir("", "create-test-plugin") ++ tmpDir, err := os.MkdirTemp("", "create-test-plugin") + if err != nil { + return err + } +@@ -79,7 +78,7 @@ func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) + // the plugin to exist on any of the daemons (immediately) and there needs to be + // some way to distribute the plugin. + func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error { +- tmpDir, err := ioutil.TempDir("", "create-test-plugin-local") ++ tmpDir, err := os.MkdirTemp("", "create-test-plugin-local") + if err != nil { + return err + } +@@ -133,7 +132,7 @@ func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, + if auth == nil { + auth = &types.AuthConfig{} + } +- err = manager.Push(ctx, repo, nil, auth, ioutil.Discard) ++ err = manager.Push(ctx, repo, nil, auth, io.Discard) + return errors.Wrap(err, "error pushing plugin") + } + +@@ -163,7 +162,7 @@ func makePluginBundle(inPath string, opts ...CreateOpt) (io.ReadCloser, error) { + if err != nil { + return nil, err + } +- if err := ioutil.WriteFile(filepath.Join(inPath, "config.json"), configJSON, 0644); err != nil { ++ if err := os.WriteFile(filepath.Join(inPath, "config.json"), configJSON, 0644); err != nil { + return nil, err + } + if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(p.Entrypoint[0])), 0755); err != nil { +diff --git a/testutil/registry/registry.go b/testutil/registry/registry.go +index d8213a3bec..5de61620c0 100644 +--- a/testutil/registry/registry.go ++++ b/testutil/registry/registry.go +@@ -3,7 +3,6 @@ package registry // import "github.com/docker/docker/testutil/registry" + import ( + "fmt" + "io" +- "io/ioutil" + "net/http" + "os" + "os/exec" +@@ -54,7 +53,7 @@ func NewV2(t testing.TB, ops ...func(*Config)) *V2 { + for _, op := range ops { + op(c) + } +- tmp, err := ioutil.TempDir("", "registry-test-") ++ tmp, err := os.MkdirTemp("", "registry-test-") + assert.NilError(t, err) + template := `version: 0.1 + loglevel: debug +@@ -79,7 +78,7 @@ http: + username = "testuser" + password = "testpassword" + email = "test@test.org" +- err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)) ++ err := os.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)) + assert.NilError(t, err) + authTemplate = fmt.Sprintf(`auth: + htpasswd: +@@ -183,7 +182,7 @@ func (r *V2) getBlobFilename(blobDigest digest.Digest) string { + func (r *V2) ReadBlobContents(t testing.TB, blobDigest digest.Digest) []byte { + t.Helper() + // Load the target manifest blob. +- manifestBlob, err := ioutil.ReadFile(r.getBlobFilename(blobDigest)) ++ manifestBlob, err := os.ReadFile(r.getBlobFilename(blobDigest)) + assert.NilError(t, err, "unable to read blob") + return manifestBlob + } +@@ -191,7 +190,7 @@ func (r *V2) ReadBlobContents(t testing.TB, blobDigest digest.Digest) []byte { + // WriteBlobContents write the file corresponding to the specified digest with the given content + func (r *V2) WriteBlobContents(t testing.TB, blobDigest digest.Digest, data []byte) { + t.Helper() +- err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644)) ++ err := os.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644)) + assert.NilError(t, err, "unable to write malicious data blob") + } + +@@ -199,7 +198,7 @@ func (r *V2) WriteBlobContents(t testing.TB, blobDigest digest.Digest, data []by + // malicious blob of data for example. + func (r *V2) TempMoveBlobData(t testing.TB, blobDigest digest.Digest) (undo func()) { + t.Helper() +- tempFile, err := ioutil.TempFile("", "registry-temp-blob-") ++ tempFile, err := os.CreateTemp("", "registry-temp-blob-") + assert.NilError(t, err, "unable to get temporary blob file") + tempFile.Close() + +diff --git a/testutil/request/ops.go b/testutil/request/ops.go +index c85308c476..be4e502ccb 100644 +--- a/testutil/request/ops.go ++++ b/testutil/request/ops.go +@@ -4,7 +4,6 @@ import ( + "bytes" + "encoding/json" + "io" +- "io/ioutil" + "net/http" + "strings" + ) +@@ -39,7 +38,7 @@ func Method(method string) func(*Options) { + + // RawString sets the specified string as body for the request + func RawString(content string) func(*Options) { +- return RawContent(ioutil.NopCloser(strings.NewReader(content))) ++ return RawContent(io.NopCloser(strings.NewReader(content))) + } + + // RawContent sets the specified reader as body for the request +@@ -71,7 +70,7 @@ func JSONBody(data interface{}) func(*Options) { + if err := json.NewEncoder(jsonData).Encode(data); err != nil { + return err + } +- req.Body = ioutil.NopCloser(jsonData) ++ req.Body = io.NopCloser(jsonData) + req.Header.Set("Content-Type", "application/json") + return nil + }) +diff --git a/testutil/request/request.go b/testutil/request/request.go +index 3efa77c17d..4f82012684 100644 +--- a/testutil/request/request.go ++++ b/testutil/request/request.go +@@ -5,7 +5,6 @@ import ( + "crypto/tls" + "fmt" + "io" +- "io/ioutil" + "net" + "net/http" + "net/url" +@@ -106,7 +105,7 @@ func Do(endpoint string, modifiers ...func(*Options)) (*http.Response, io.ReadCl + // ReadBody read the specified ReadCloser content and returns it + func ReadBody(b io.ReadCloser) ([]byte, error) { + defer b.Close() +- return ioutil.ReadAll(b) ++ return io.ReadAll(b) + } + + // newRequest creates a new http Request to the specified host and endpoint, with the specified request modifiers +diff --git a/volume/local/local.go b/volume/local/local.go +index 088502f43b..29e3cc9a54 100644 +--- a/volume/local/local.go ++++ b/volume/local/local.go +@@ -6,7 +6,6 @@ package local // import "github.com/docker/docker/volume/local" + import ( + "encoding/json" + "fmt" +- "io/ioutil" + "os" + "path/filepath" + "reflect" +@@ -61,7 +60,7 @@ func New(scope string, rootIdentity idtools.Identity) (*Root, error) { + rootIdentity: rootIdentity, + } + +- dirs, err := ioutil.ReadDir(rootDirectory) ++ dirs, err := os.ReadDir(rootDirectory) + if err != nil { + return nil, err + } +@@ -84,7 +83,7 @@ func New(scope string, rootIdentity idtools.Identity) (*Root, error) { + } + r.volumes[name] = v + optsFilePath := filepath.Join(rootDirectory, name, "opts.json") +- if b, err := ioutil.ReadFile(optsFilePath); err == nil { ++ if b, err := os.ReadFile(optsFilePath); err == nil { + opts := optsConfig{} + if err := json.Unmarshal(b, &opts); err != nil { + return nil, errors.Wrapf(err, "error while unmarshaling volume options for volume: %s", name) +@@ -187,7 +186,7 @@ func (r *Root) Create(name string, opts map[string]string) (volume.Volume, error + if err != nil { + return nil, err + } +- if err = ioutil.WriteFile(filepath.Join(filepath.Dir(path), "opts.json"), b, 0600); err != nil { ++ if err = os.WriteFile(filepath.Join(filepath.Dir(path), "opts.json"), b, 0600); err != nil { + return nil, errdefs.System(errors.Wrap(err, "error while persisting volume options")) + } + } +diff --git a/volume/local/local_linux_test.go b/volume/local/local_linux_test.go +index 9b150a2e6d..c66ecc9095 100644 +--- a/volume/local/local_linux_test.go ++++ b/volume/local/local_linux_test.go +@@ -4,7 +4,6 @@ + package local // import "github.com/docker/docker/volume/local" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -59,11 +58,11 @@ func testVolWithQuota(t *testing.T, mountPoint, backingFsDev, testDir string) { + testfile := filepath.Join(dir, "testfile") + + // test writing file smaller than quota +- assert.NilError(t, ioutil.WriteFile(testfile, make([]byte, quotaSize/2), 0644)) ++ assert.NilError(t, os.WriteFile(testfile, make([]byte, quotaSize/2), 0644)) + assert.NilError(t, os.Remove(testfile)) + + // test writing fiel larger than quota +- err = ioutil.WriteFile(testfile, make([]byte, quotaSize+1), 0644) ++ err = os.WriteFile(testfile, make([]byte, quotaSize+1), 0644) + assert.ErrorContains(t, err, "") + if _, err := os.Stat(testfile); err == nil { + assert.NilError(t, os.Remove(testfile)) +diff --git a/volume/local/local_test.go b/volume/local/local_test.go +index 8045e87a0e..180ad09380 100644 +--- a/volume/local/local_test.go ++++ b/volume/local/local_test.go +@@ -1,7 +1,6 @@ + package local // import "github.com/docker/docker/volume/local" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "reflect" +@@ -32,7 +31,7 @@ func TestGetAddress(t *testing.T) { + + func TestRemove(t *testing.T) { + skip.If(t, runtime.GOOS == "windows", "FIXME: investigate why this test fails on CI") +- rootDir, err := ioutil.TempDir("", "local-volume-test") ++ rootDir, err := os.MkdirTemp("", "local-volume-test") + if err != nil { + t.Fatal(err) + } +@@ -74,7 +73,7 @@ func TestRemove(t *testing.T) { + } + + func TestInitializeWithVolumes(t *testing.T) { +- rootDir, err := ioutil.TempDir("", "local-volume-test") ++ rootDir, err := os.MkdirTemp("", "local-volume-test") + if err != nil { + t.Fatal(err) + } +@@ -106,7 +105,7 @@ func TestInitializeWithVolumes(t *testing.T) { + } + + func TestCreate(t *testing.T) { +- rootDir, err := ioutil.TempDir("", "local-volume-test") ++ rootDir, err := os.MkdirTemp("", "local-volume-test") + if err != nil { + t.Fatal(err) + } +@@ -180,7 +179,7 @@ func TestValidateName(t *testing.T) { + func TestCreateWithOpts(t *testing.T) { + skip.If(t, runtime.GOOS == "windows") + skip.If(t, os.Getuid() != 0, "requires mounts") +- rootDir, err := ioutil.TempDir("", "local-volume-test") ++ rootDir, err := os.MkdirTemp("", "local-volume-test") + if err != nil { + t.Fatal(err) + } +@@ -277,7 +276,7 @@ func TestCreateWithOpts(t *testing.T) { + } + + func TestRelaodNoOpts(t *testing.T) { +- rootDir, err := ioutil.TempDir("", "volume-test-reload-no-opts") ++ rootDir, err := os.MkdirTemp("", "volume-test-reload-no-opts") + if err != nil { + t.Fatal(err) + } +@@ -295,7 +294,7 @@ func TestRelaodNoOpts(t *testing.T) { + t.Fatal(err) + } + // make sure a file with `null` (.e.g. empty opts map from older daemon) is ok +- if err := ioutil.WriteFile(filepath.Join(rootDir, "test2"), []byte("null"), 0600); err != nil { ++ if err := os.WriteFile(filepath.Join(rootDir, "test2"), []byte("null"), 0600); err != nil { + t.Fatal(err) + } + +@@ -303,7 +302,7 @@ func TestRelaodNoOpts(t *testing.T) { + t.Fatal(err) + } + // make sure an empty opts file doesn't break us too +- if err := ioutil.WriteFile(filepath.Join(rootDir, "test3"), nil, 0600); err != nil { ++ if err := os.WriteFile(filepath.Join(rootDir, "test3"), nil, 0600); err != nil { + t.Fatal(err) + } + +diff --git a/volume/mounts/parser_test.go b/volume/mounts/parser_test.go +index c879c3b152..44efd19de8 100644 +--- a/volume/mounts/parser_test.go ++++ b/volume/mounts/parser_test.go +@@ -2,7 +2,6 @@ package mounts // import "github.com/docker/docker/volume/mounts" + + import ( + "errors" +- "io/ioutil" + "os" + "runtime" + "strings" +@@ -436,7 +435,7 @@ func TestParseMountSpec(t *testing.T) { + input mount.Mount + expected MountPoint + } +- testDir, err := ioutil.TempDir("", "test-mount-config") ++ testDir, err := os.MkdirTemp("", "test-mount-config") + if err != nil { + t.Fatal(err) + } +diff --git a/volume/mounts/validate_test.go b/volume/mounts/validate_test.go +index 4f83856043..390c8850a5 100644 +--- a/volume/mounts/validate_test.go ++++ b/volume/mounts/validate_test.go +@@ -2,7 +2,6 @@ package mounts // import "github.com/docker/docker/volume/mounts" + + import ( + "errors" +- "io/ioutil" + "os" + "runtime" + "strings" +@@ -12,7 +11,7 @@ import ( + ) + + func TestValidateMount(t *testing.T) { +- testDir, err := ioutil.TempDir("", "test-validate-mount") ++ testDir, err := os.MkdirTemp("", "test-validate-mount") + if err != nil { + t.Fatal(err) + } +diff --git a/volume/service/db_test.go b/volume/service/db_test.go +index b7e2424b43..002aba5668 100644 +--- a/volume/service/db_test.go ++++ b/volume/service/db_test.go +@@ -1,7 +1,6 @@ + package service // import "github.com/docker/docker/volume/service" + + import ( +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -15,7 +14,7 @@ import ( + func TestSetGetMeta(t *testing.T) { + t.Parallel() + +- dir, err := ioutil.TempDir("", "test-set-get") ++ dir, err := os.MkdirTemp("", "test-set-get") + assert.NilError(t, err) + defer os.RemoveAll(dir) + +diff --git a/volume/service/restore_test.go b/volume/service/restore_test.go +index bf528bb935..e943e55f62 100644 +--- a/volume/service/restore_test.go ++++ b/volume/service/restore_test.go +@@ -2,7 +2,6 @@ package service // import "github.com/docker/docker/volume/service" + + import ( + "context" +- "io/ioutil" + "os" + "testing" + +@@ -16,7 +15,7 @@ import ( + func TestRestore(t *testing.T) { + t.Parallel() + +- dir, err := ioutil.TempDir("", "test-restore") ++ dir, err := os.MkdirTemp("", "test-restore") + assert.NilError(t, err) + defer os.RemoveAll(dir) + +diff --git a/volume/service/service_linux_test.go b/volume/service/service_linux_test.go +index fec9f7f358..d29aabe856 100644 +--- a/volume/service/service_linux_test.go ++++ b/volume/service/service_linux_test.go +@@ -2,7 +2,6 @@ package service + + import ( + "context" +- "io/ioutil" + "os" + "path/filepath" + "testing" +@@ -21,7 +20,7 @@ func TestLocalVolumeSize(t *testing.T) { + t.Parallel() + + ds := volumedrivers.NewStore(nil) +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + defer os.RemoveAll(dir) + +@@ -42,9 +41,9 @@ func TestLocalVolumeSize(t *testing.T) { + assert.NilError(t, err) + + data := make([]byte, 1024) +- err = ioutil.WriteFile(filepath.Join(v1.Mountpoint, "data"), data, 0644) ++ err = os.WriteFile(filepath.Join(v1.Mountpoint, "data"), data, 0644) + assert.NilError(t, err) +- err = ioutil.WriteFile(filepath.Join(v2.Mountpoint, "data"), data[:1], 0644) ++ err = os.WriteFile(filepath.Join(v2.Mountpoint, "data"), data[:1], 0644) + assert.NilError(t, err) + + ls, err := service.LocalVolumesSize(ctx) +diff --git a/volume/service/service_test.go b/volume/service/service_test.go +index 9a9f349bcd..289315d090 100644 +--- a/volume/service/service_test.go ++++ b/volume/service/service_test.go +@@ -2,7 +2,6 @@ package service + + import ( + "context" +- "io/ioutil" + "os" + "testing" + +@@ -236,7 +235,7 @@ func TestServicePrune(t *testing.T) { + func newTestService(t *testing.T, ds *volumedrivers.Store) (*VolumesService, func()) { + t.Helper() + +- dir, err := ioutil.TempDir("", t.Name()) ++ dir, err := os.MkdirTemp("", t.Name()) + assert.NilError(t, err) + + store, err := NewStore(dir, ds) +diff --git a/volume/service/store_test.go b/volume/service/store_test.go +index 5442f4558c..97c521717d 100644 +--- a/volume/service/store_test.go ++++ b/volume/service/store_test.go +@@ -4,7 +4,6 @@ import ( + "context" + "errors" + "fmt" +- "io/ioutil" + "net" + "os" + "strings" +@@ -87,7 +86,7 @@ func TestRemove(t *testing.T) { + func TestList(t *testing.T) { + t.Parallel() + +- dir, err := ioutil.TempDir("", "test-list") ++ dir, err := os.MkdirTemp("", "test-list") + assert.NilError(t, err) + defer os.RemoveAll(dir) + +@@ -369,7 +368,7 @@ func setupTest(t *testing.T) (*VolumeStore, func()) { + t.Helper() + + dirName := strings.Replace(t.Name(), string(os.PathSeparator), "_", -1) +- dir, err := ioutil.TempDir("", dirName) ++ dir, err := os.MkdirTemp("", dirName) + assert.NilError(t, err) + + cleanup := func() { +-- +2.21.0 + diff --git a/patch/backport-0004-moby20.10-hack-remove-non-existent-directories-from-golangci-l.patch b/patch/backport-0004-moby20.10-hack-remove-non-existent-directories-from-golangci-l.patch new file mode 100644 index 0000000..86d13d4 --- /dev/null +++ b/patch/backport-0004-moby20.10-hack-remove-non-existent-directories-from-golangci-l.patch @@ -0,0 +1,28 @@ +From ddae0d6381dee5be27f96c0d11d10320bc013991 Mon Sep 17 00:00:00 2001 +From: Kazuyoshi Kato +Date: Mon, 27 Dec 2021 09:38:43 -0800 +Subject: [PATCH 04/16] hack: remove non-existent directories from + golangci-lint's skip-dirs + +Signed-off-by: Kazuyoshi Kato +(cherry picked from commit 136f93ea052aeed008189749e16fa4f2b1f7fae8) +Signed-off-by: Cory Snider +--- + hack/validate/golangci-lint.yml | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/hack/validate/golangci-lint.yml b/hack/validate/golangci-lint.yml +index 649081139a..6fac7d2324 100644 +--- a/hack/validate/golangci-lint.yml ++++ b/hack/validate/golangci-lint.yml +@@ -23,7 +23,6 @@ linters: + modules-download-mode: vendor + + skip-dirs: +- - bundles + - docs + + linters-settings: +-- +2.21.0 + diff --git a/patch/backport-0005-moby20.10-hack-do-not-exclude-SQL-related-checks.patch b/patch/backport-0005-moby20.10-hack-do-not-exclude-SQL-related-checks.patch new file mode 100644 index 0000000..86185a0 --- /dev/null +++ b/patch/backport-0005-moby20.10-hack-do-not-exclude-SQL-related-checks.patch @@ -0,0 +1,31 @@ +From 71259512361555f97f834c8a22f7973985ba6ba3 Mon Sep 17 00:00:00 2001 +From: Kazuyoshi Kato +Date: Mon, 27 Dec 2021 09:49:46 -0800 +Subject: [PATCH 05/16] hack: do not exclude SQL-related checks + +moby doesn't have SQLs right now. + +Signed-off-by: Kazuyoshi Kato +(cherry picked from commit 22f19f82439725ffa813e2bc42a2f62cd5f882d0) +Signed-off-by: Cory Snider +--- + hack/validate/golangci-lint.yml | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/hack/validate/golangci-lint.yml b/hack/validate/golangci-lint.yml +index 6fac7d2324..02fa07c31f 100644 +--- a/hack/validate/golangci-lint.yml ++++ b/hack/validate/golangci-lint.yml +@@ -96,9 +96,6 @@ issues: + path: "api/types/(volume|container)/" + linters: + - golint +- - text: "(G201|G202): SQL string (formatting|concatenation)" +- linters: +- - gosec + # FIXME: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close" (gosec) + - text: "G307: Deferring unsafe method" + linters: +-- +2.21.0 + diff --git a/patch/backport-0006-moby20.10-hack-remove-a-workaround-for-go-tools.patch b/patch/backport-0006-moby20.10-hack-remove-a-workaround-for-go-tools.patch new file mode 100644 index 0000000..cf883ad --- /dev/null +++ b/patch/backport-0006-moby20.10-hack-remove-a-workaround-for-go-tools.patch @@ -0,0 +1,33 @@ +From 063042449ec8d356d6948052e4d80e9a676cb065 Mon Sep 17 00:00:00 2001 +From: Kazuyoshi Kato +Date: Mon, 27 Dec 2021 09:50:23 -0800 +Subject: [PATCH 06/16] hack: remove a workaround for go-tools + +The false positive has been fixed. + +Signed-off-by: Kazuyoshi Kato +(cherry picked from commit 4bdc20844935c5995637b40bdb8152640d2e0c1f) +Signed-off-by: Cory Snider +--- + hack/validate/golangci-lint.yml | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/hack/validate/golangci-lint.yml b/hack/validate/golangci-lint.yml +index 02fa07c31f..3fc86963d8 100644 +--- a/hack/validate/golangci-lint.yml ++++ b/hack/validate/golangci-lint.yml +@@ -112,11 +112,6 @@ issues: + - text: "SA1019: httputil.ErrPersistEOF" + linters: + - staticcheck +- # FIXME temporarily suppress these for false positives in tests (see https://github.com/dominikh/go-tools/issues/1022) +- - text: "SA5011" +- path: _test\.go +- linters: +- - staticcheck + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-issues-per-linter: 0 +-- +2.21.0 + diff --git a/patch/backport-0007-moby20.10-linting-error-strings-should-not-be-capitalized-revi.patch b/patch/backport-0007-moby20.10-linting-error-strings-should-not-be-capitalized-revi.patch new file mode 100644 index 0000000..db1b102 --- /dev/null +++ b/patch/backport-0007-moby20.10-linting-error-strings-should-not-be-capitalized-revi.patch @@ -0,0 +1,72 @@ +From 2461d88305974822c5829a744a30a297a740a83f Mon Sep 17 00:00:00 2001 +From: Sebastiaan van Stijn +Date: Mon, 4 Jul 2022 10:07:58 +0200 +Subject: [PATCH 07/16] linting: error strings should not be capitalized + (revive) + + client/request.go:183:28: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive) + err = errors.Wrap(err, "In the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect.") + ^ + client/request.go:186:28: error-strings: error strings should not be capitalized or end with punctuation or a newline (revive) + err = errors.Wrap(err, "This error may indicate that the docker daemon is not running.") + ^ + +Signed-off-by: Sebastiaan van Stijn +(cherry picked from commit 10c56efa9730cc84274593de89c4cc90cbc83ae6) +Signed-off-by: Cory Snider +--- + client/request.go | 8 ++++---- + daemon/network.go | 2 +- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/client/request.go b/client/request.go +index f07a6cade6..d3d9a3fe64 100644 +--- a/client/request.go ++++ b/client/request.go +@@ -128,7 +128,7 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp + } + + if cli.scheme == "https" && strings.Contains(err.Error(), "bad certificate") { +- return serverResp, errors.Wrap(err, "The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings") ++ return serverResp, errors.Wrap(err, "the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings") + } + + // Don't decorate context sentinel errors; users may be comparing to +@@ -140,7 +140,7 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp + if nErr, ok := err.(*url.Error); ok { + if nErr, ok := nErr.Err.(*net.OpError); ok { + if os.IsPermission(nErr.Err) { +- return serverResp, errors.Wrapf(err, "Got permission denied while trying to connect to the Docker daemon socket at %v", cli.host) ++ return serverResp, errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host) + } + } + } +@@ -167,10 +167,10 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp + if strings.Contains(err.Error(), `open //./pipe/docker_engine`) { + // Checks if client is running with elevated privileges + if f, elevatedErr := os.Open("\\\\.\\PHYSICALDRIVE0"); elevatedErr == nil { +- err = errors.Wrap(err, "In the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect.") ++ err = errors.Wrap(err, "in the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect") + } else { + f.Close() +- err = errors.Wrap(err, "This error may indicate that the docker daemon is not running.") ++ err = errors.Wrap(err, "this error may indicate that the docker daemon is not running") + } + } + +diff --git a/daemon/network.go b/daemon/network.go +index 2cc84e4a00..0fcaf4d809 100644 +--- a/daemon/network.go ++++ b/daemon/network.go +@@ -356,7 +356,7 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string + if agent && driver == "overlay" { + nodeIP, exists := daemon.GetAttachmentStore().GetIPForNetwork(id) + if !exists { +- return nil, fmt.Errorf("Failed to find a load balancer IP to use for network: %v", id) ++ return nil, fmt.Errorf("failed to find a load balancer IP to use for network: %v", id) + } + + nwOptions = append(nwOptions, libnetwork.NetworkOptionLBEndpoint(nodeIP)) +-- +2.21.0 + diff --git a/patch/backport-0008-moby20.10-fix-some-minor-linting-issues.patch b/patch/backport-0008-moby20.10-fix-some-minor-linting-issues.patch new file mode 100644 index 0000000..fe9712e --- /dev/null +++ b/patch/backport-0008-moby20.10-fix-some-minor-linting-issues.patch @@ -0,0 +1,76 @@ +From 057ea3492e14b6cd4e023057320c9e81ac34643a Mon Sep 17 00:00:00 2001 +From: Sebastiaan van Stijn +Date: Mon, 4 Jul 2022 10:12:20 +0200 +Subject: [PATCH 08/16] fix some minor linting issues + + distribution/pull_v2_test.go:213:4: S1038: should use t.Fatalf(...) instead of t.Fatal(fmt.Sprintf(...)) (gosimple) + t.Fatal(fmt.Sprintf("expected formatPlatform to show windows platform with a version, but got '%s'", result)) + ^ + integration-cli/docker_cli_build_test.go:5951:3: S1038: should use c.Skipf(...) instead of c.Skip(fmt.Sprintf(...)) (gosimple) + c.Skip(fmt.Sprintf("Bug fixed in 18.06 or higher.Skipping it for %s", testEnv.DaemonInfo.ServerVersion)) + ^ + integration-cli/docker_cli_daemon_test.go:240:3: S1038: should use c.Skipf(...) instead of c.Skip(fmt.Sprintf(...)) (gosimple) + c.Skip(fmt.Sprintf("New base device size (%v) must be greater than (%s)", units.HumanSize(float64(newBasesizeBytes)), units.HumanSize(float64(oldBasesizeBytes)))) + ^ + +Signed-off-by: Sebastiaan van Stijn +(cherry picked from commit 968ff5ab44b1846964e832d4509e17f814d6116d) +Signed-off-by: Cory Snider +--- + distribution/pull_v2_test.go | 3 +-- + integration-cli/docker_cli_build_test.go | 4 ---- + integration-cli/docker_cli_daemon_test.go | 2 +- + 3 files changed, 2 insertions(+), 7 deletions(-) + +diff --git a/distribution/pull_v2_test.go b/distribution/pull_v2_test.go +index 1eaa265005..31fa336bdc 100644 +--- a/distribution/pull_v2_test.go ++++ b/distribution/pull_v2_test.go +@@ -3,7 +3,6 @@ package distribution // import "github.com/docker/docker/distribution" + import ( + "context" + "encoding/json" +- "fmt" + "net/http" + "net/http/httptest" + "net/url" +@@ -210,7 +209,7 @@ func TestFormatPlatform(t *testing.T) { + } + matches, _ := regexp.MatchString("windows.* [0-9]", result) + if !matches { +- t.Fatal(fmt.Sprintf("expected formatPlatform to show windows platform with a version, but got '%s'", result)) ++ t.Fatalf("expected formatPlatform to show windows platform with a version, but got '%s'", result) + } + } + } +diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go +index 34f61b450f..0b1911a5de 100644 +--- a/integration-cli/docker_cli_build_test.go ++++ b/integration-cli/docker_cli_build_test.go +@@ -5936,10 +5936,6 @@ func (s *DockerSuite) TestBuildMultiStageResetScratch(c *testing.T) { + } + + func (s *DockerSuite) TestBuildIntermediateTarget(c *testing.T) { +- //todo: need to be removed after 18.06 release +- if strings.Contains(testEnv.DaemonInfo.ServerVersion, "18.05.0") { +- c.Skip(fmt.Sprintf("Bug fixed in 18.06 or higher.Skipping it for %s", testEnv.DaemonInfo.ServerVersion)) +- } + dockerfile := ` + FROM busybox AS build-env + CMD ["/dev"] +diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go +index 443f12e96e..74ce390257 100644 +--- a/integration-cli/docker_cli_daemon_test.go ++++ b/integration-cli/docker_cli_daemon_test.go +@@ -237,7 +237,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithIncreasedBasesize(c *testing.T) + var newBasesizeBytes int64 = 53687091200 // 50GB in bytes + + if newBasesizeBytes < oldBasesizeBytes { +- c.Skip(fmt.Sprintf("New base device size (%v) must be greater than (%s)", units.HumanSize(float64(newBasesizeBytes)), units.HumanSize(float64(oldBasesizeBytes)))) ++ c.Skipf("New base device size (%v) must be greater than (%s)", units.HumanSize(float64(newBasesizeBytes)), units.HumanSize(float64(oldBasesizeBytes))) + } + + err := s.d.RestartWithError("--storage-opt", fmt.Sprintf("dm.basesize=%d", newBasesizeBytes)) +-- +2.21.0 + diff --git a/patch/backport-0009-moby20.10-hack-update-golangci-lint-to-v1.46.2.patch b/patch/backport-0009-moby20.10-hack-update-golangci-lint-to-v1.46.2.patch new file mode 100644 index 0000000..0c3b5cf --- /dev/null +++ b/patch/backport-0009-moby20.10-hack-update-golangci-lint-to-v1.46.2.patch @@ -0,0 +1,41 @@ +From 432fbc8638177a0f160e09dd6a3b8f044ec1e081 Mon Sep 17 00:00:00 2001 +From: Sebastiaan van Stijn +Date: Sat, 2 Jul 2022 19:20:06 +0200 +Subject: [PATCH 09/16] hack: update golangci-lint to v1.46.2 + +Signed-off-by: Sebastiaan van Stijn +(cherry picked from commit 65e1adc219f4b1b71f09479aa98be87135a579d5) +Signed-off-by: Cory Snider +--- + hack/dockerfile/install/golangci_lint.installer | 2 +- + hack/validate/golangci-lint.yml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hack/dockerfile/install/golangci_lint.installer b/hack/dockerfile/install/golangci_lint.installer +index 0043c079b9..c6f4b44d16 100755 +--- a/hack/dockerfile/install/golangci_lint.installer ++++ b/hack/dockerfile/install/golangci_lint.installer +@@ -1,6 +1,6 @@ + #!/bin/sh + +-: "${GOLANGCI_LINT_VERSION=v1.44.0}" ++: "${GOLANGCI_LINT_VERSION=v1.46.2}" + + install_golangci_lint() { + set -e +diff --git a/hack/validate/golangci-lint.yml b/hack/validate/golangci-lint.yml +index 3fc86963d8..f4d51891b3 100644 +--- a/hack/validate/golangci-lint.yml ++++ b/hack/validate/golangci-lint.yml +@@ -42,7 +42,7 @@ issues: + # ID's. + # + # These exclusion patterns are copied from the default excluses at: +- # https://github.com/golangci/golangci-lint/blob/v1.44.0/pkg/config/issues.go#L10-L104 ++ # https://github.com/golangci/golangci-lint/blob/v1.46.2/pkg/config/issues.go#L10-L104 + + # EXC0001 + - text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked" +-- +2.21.0 + diff --git a/patch/backport-0010-moby20.10-replace-golint-with-revive-as-it-s-deprecated.patch b/patch/backport-0010-moby20.10-replace-golint-with-revive-as-it-s-deprecated.patch new file mode 100644 index 0000000..30df70f --- /dev/null +++ b/patch/backport-0010-moby20.10-replace-golint-with-revive-as-it-s-deprecated.patch @@ -0,0 +1,83 @@ +From 78d8e65d2a2420d47ca191520aa4b8691968ebbb Mon Sep 17 00:00:00 2001 +From: Sebastiaan van Stijn +Date: Sat, 2 Jul 2022 21:51:37 +0200 +Subject: [PATCH 10/16] replace golint with revive, as it's deprecated + + WARN [runner] The linter 'golint' is deprecated (since v1.41.0) due to: The repository of the linter has been archived by the owner. Replaced by revive. + +Signed-off-by: Sebastiaan van Stijn +(cherry picked from commit 1cab8eda24e70c60061e34adc4a19c1aeb5ad90c) +Signed-off-by: Cory Snider +--- + daemon/network.go | 2 +- + hack/validate/golangci-lint.yml | 8 ++------ + integration/internal/network/network.go | 2 +- + 3 files changed, 4 insertions(+), 8 deletions(-) + +diff --git a/daemon/network.go b/daemon/network.go +index 0fcaf4d809..0a57b39394 100644 +--- a/daemon/network.go ++++ b/daemon/network.go +@@ -365,7 +365,7 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string + n, err := c.NewNetwork(driver, create.Name, id, nwOptions...) + if err != nil { + if _, ok := err.(libnetwork.ErrDataStoreNotInitialized); ok { +- //nolint: golint ++ //nolint: revive + return nil, errors.New("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.") + } + return nil, err +diff --git a/hack/validate/golangci-lint.yml b/hack/validate/golangci-lint.yml +index f4d51891b3..d3b0d5fae4 100644 +--- a/hack/validate/golangci-lint.yml ++++ b/hack/validate/golangci-lint.yml +@@ -2,12 +2,12 @@ linters: + enable: + - deadcode + - goimports +- - golint + - gosec + - gosimple + - govet + - ineffassign + - misspell ++ - revive + - staticcheck + - structcheck + - typecheck +@@ -48,10 +48,6 @@ issues: + - text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked" + linters: + - errcheck +- # EXC0003 +- - text: "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this" +- linters: +- - golint + # EXC0006 + - text: "Use of unsafe calls should be audited" + linters: +@@ -95,7 +91,7 @@ issues: + - text: "type name will be used as (container|volume)\\.(Container|Volume).* by other packages, and that stutters; consider calling this" + path: "api/types/(volume|container)/" + linters: +- - golint ++ - revive + # FIXME: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close" (gosec) + - text: "G307: Deferring unsafe method" + linters: +diff --git a/integration/internal/network/network.go b/integration/internal/network/network.go +index 04f29c7bb2..5a682ce84d 100644 +--- a/integration/internal/network/network.go ++++ b/integration/internal/network/network.go +@@ -26,7 +26,7 @@ func Create(ctx context.Context, client client.APIClient, name string, ops ...fu + } + + // CreateNoError creates a network with the specified options and verifies there were no errors +-func CreateNoError(ctx context.Context, t *testing.T, client client.APIClient, name string, ops ...func(*types.NetworkCreate)) string { //nolint: golint ++func CreateNoError(ctx context.Context, t *testing.T, client client.APIClient, name string, ops ...func(*types.NetworkCreate)) string { + t.Helper() + + name, err := createNetwork(ctx, client, name, ops...) +-- +2.21.0 + diff --git a/patch/backport-0011-moby20.10-gofmt-GoDoc-comments-with-go1.19.patch b/patch/backport-0011-moby20.10-gofmt-GoDoc-comments-with-go1.19.patch new file mode 100644 index 0000000..28cd3a9 --- /dev/null +++ b/patch/backport-0011-moby20.10-gofmt-GoDoc-comments-with-go1.19.patch @@ -0,0 +1,1807 @@ +From c8c40abbba789d50f27d041c6a1a0280022356aa Mon Sep 17 00:00:00 2001 +From: Sebastiaan van Stijn +Date: Fri, 8 Jul 2022 18:27:07 +0200 +Subject: [PATCH 11/16] gofmt GoDoc comments with go1.19 + +Older versions of Go don't format comments, so committing this as +a separate commit, so that we can already make these changes before +we upgrade to Go 1.19. + +Signed-off-by: Sebastiaan van Stijn +(cherry picked from commit 52c1a2fae8ffe3efc8b24ef53a702582131ebc57) +Signed-off-by: Sebastiaan van Stijn +(cherry picked from commit cdbca4061ba2e45924e0ce93c8c3afb5c8de4a9f) +Signed-off-by: Cory Snider +--- + api/types/filters/parse.go | 3 +- + api/types/registry/registry.go | 49 +++---- + api/types/time/timestamp.go | 6 +- + builder/dockerfile/dispatchers.go | 13 -- + builder/remotecontext/remote.go | 8 +- + client/client.go | 3 +- + client/container_attach.go | 2 +- + client/container_logs.go | 2 +- + cmd/dockerd/daemon.go | 2 +- + container/container.go | 18 +-- + daemon/cluster/listen_addr.go | 6 +- + daemon/container.go | 10 +- + daemon/content.go | 3 +- + daemon/daemon_unix.go | 15 ++- + daemon/graphdriver/fsdiff.go | 9 +- + daemon/graphdriver/lcow/lcow_svm.go | 42 +++--- + daemon/images/image.go | 2 +- + daemon/images/image_commit.go | 6 +- + daemon/images/image_delete.go | 11 +- + daemon/info_unix.go | 8 +- + daemon/top_windows.go | 25 ++-- + dockerversion/useragent.go | 6 +- + hack/make/.resources-windows/resources.go | 8 +- + .../docker_cli_cp_from_container_test.go | 71 +++++----- + .../docker_cli_cp_to_container_test.go | 71 +++++----- + .../docker_cli_external_volume_driver_test.go | 3 +- + integration/container/ipcmode_linux_test.go | 6 +- + integration/image/pull_test.go | 2 +- + integration/internal/container/exec.go | 4 +- + integration/service/create_test.go | 4 +- + .../system/cgroupdriver_systemd_test.go | 2 +- + libcontainerd/local/local_windows.go | 68 +++++----- + oci/oci.go | 15 ++- + pkg/archive/archive.go | 3 +- + pkg/archive/archive_linux_test.go | 15 ++- + pkg/archive/copy_unix_test.go | 123 ++++++++++-------- + pkg/archive/wrap.go | 4 +- + pkg/chrootarchive/archive.go | 2 +- + pkg/devicemapper/devmapper.go | 2 +- + pkg/devicemapper/devmapper_log.go | 1 + + pkg/mount/deprecated.go | 2 + + pkg/mount/deprecated_linux.go | 1 + + pkg/mount/deprecated_unix.go | 3 + + pkg/parsers/parsers.go | 30 +++-- + pkg/plugins/plugins.go | 2 +- + pkg/signal/trap.go | 15 +-- + pkg/system/meminfo_windows.go | 2 +- + plugin/store.go | 14 +- + quota/projectquota.go | 8 +- + volume/drivers/extpoint.go | 4 +- + volume/service/store.go | 8 +- + 51 files changed, 389 insertions(+), 353 deletions(-) + +diff --git a/api/types/filters/parse.go b/api/types/filters/parse.go +index 63db4c617b..b4976a3471 100644 +--- a/api/types/filters/parse.go ++++ b/api/types/filters/parse.go +@@ -1,4 +1,5 @@ +-/*Package filters provides tools for encoding a mapping of keys to a set of ++/* ++Package filters provides tools for encoding a mapping of keys to a set of + multiple values. + */ + package filters // import "github.com/docker/docker/api/types/filters" +diff --git a/api/types/registry/registry.go b/api/types/registry/registry.go +index 53e47084c8..62a88f5be8 100644 +--- a/api/types/registry/registry.go ++++ b/api/types/registry/registry.go +@@ -45,31 +45,32 @@ func (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) { + // IndexInfo contains information about a registry + // + // RepositoryInfo Examples: +-// { +-// "Index" : { +-// "Name" : "docker.io", +-// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"], +-// "Secure" : true, +-// "Official" : true, +-// }, +-// "RemoteName" : "library/debian", +-// "LocalName" : "debian", +-// "CanonicalName" : "docker.io/debian" +-// "Official" : true, +-// } + // +-// { +-// "Index" : { +-// "Name" : "127.0.0.1:5000", +-// "Mirrors" : [], +-// "Secure" : false, +-// "Official" : false, +-// }, +-// "RemoteName" : "user/repo", +-// "LocalName" : "127.0.0.1:5000/user/repo", +-// "CanonicalName" : "127.0.0.1:5000/user/repo", +-// "Official" : false, +-// } ++// { ++// "Index" : { ++// "Name" : "docker.io", ++// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"], ++// "Secure" : true, ++// "Official" : true, ++// }, ++// "RemoteName" : "library/debian", ++// "LocalName" : "debian", ++// "CanonicalName" : "docker.io/debian" ++// "Official" : true, ++// } ++// ++// { ++// "Index" : { ++// "Name" : "127.0.0.1:5000", ++// "Mirrors" : [], ++// "Secure" : false, ++// "Official" : false, ++// }, ++// "RemoteName" : "user/repo", ++// "LocalName" : "127.0.0.1:5000/user/repo", ++// "CanonicalName" : "127.0.0.1:5000/user/repo", ++// "Official" : false, ++// } + type IndexInfo struct { + // Name is the name of the registry, such as "docker.io" + Name string +diff --git a/api/types/time/timestamp.go b/api/types/time/timestamp.go +index ea3495efeb..2a74b7a597 100644 +--- a/api/types/time/timestamp.go ++++ b/api/types/time/timestamp.go +@@ -100,8 +100,10 @@ func GetTimestamp(value string, reference time.Time) (string, error) { + // if the incoming nanosecond portion is longer or shorter than 9 digits it is + // converted to nanoseconds. The expectation is that the seconds and + // seconds will be used to create a time variable. For example: +-// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0) +-// if err == nil since := time.Unix(seconds, nanoseconds) ++// ++// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0) ++// if err == nil since := time.Unix(seconds, nanoseconds) ++// + // returns seconds as def(aultSeconds) if value == "" + func ParseTimestamps(value string, def int64) (int64, int64, error) { + if value == "" { +diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go +index f755f12650..f919bcb8e8 100644 +--- a/builder/dockerfile/dispatchers.go ++++ b/builder/dockerfile/dispatchers.go +@@ -35,7 +35,6 @@ import ( + // + // Sets the environment variable foo to bar, also makes interpolation + // in the dockerfile available from the next statement on via ${foo}. +-// + func dispatchEnv(d dispatchRequest, c *instructions.EnvCommand) error { + runConfig := d.state.runConfig + commitMessage := bytes.NewBufferString("ENV") +@@ -73,7 +72,6 @@ func dispatchMaintainer(d dispatchRequest, c *instructions.MaintainerCommand) er + // LABEL some json data describing the image + // + // Sets the Label variable foo to bar, +-// + func dispatchLabel(d dispatchRequest, c *instructions.LabelCommand) error { + if d.state.runConfig.Labels == nil { + d.state.runConfig.Labels = make(map[string]string) +@@ -90,7 +88,6 @@ func dispatchLabel(d dispatchRequest, c *instructions.LabelCommand) error { + // + // Add the file 'foo' to '/path'. Tarball and Remote URL (http, https) handling + // exist here. If you do not wish to have this automatic handling, use COPY. +-// + func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error { + if c.Chmod != "" { + return errors.New("the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled") +@@ -112,7 +109,6 @@ func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error { + // COPY foo /path + // + // Same as 'ADD' but without the tar and remote url handling. +-// + func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error { + if c.Chmod != "" { + return errors.New("the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled") +@@ -157,7 +153,6 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error + } + + // FROM [--platform=platform] imagename[:tag | @digest] [AS build-stage-name] +-// + func initializeStage(d dispatchRequest, cmd *instructions.Stage) error { + d.builder.imageProber.Reset() + +@@ -304,7 +299,6 @@ func dispatchOnbuild(d dispatchRequest, c *instructions.OnbuildCommand) error { + // WORKDIR /tmp + // + // Set the working directory for future RUN/CMD/etc statements. +-// + func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error { + runConfig := d.state.runConfig + var err error +@@ -347,7 +341,6 @@ func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error { + // RUN echo hi # sh -c echo hi (Linux and LCOW) + // RUN echo hi # cmd /S /C echo hi (Windows) + // RUN [ "echo", "hi" ] # echo hi +-// + func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error { + if !system.IsOSSupported(d.state.operatingSystem) { + return system.ErrNotSupportedOperatingSystem +@@ -442,7 +435,6 @@ func prependEnvOnCmd(buildArgs *BuildArgs, buildArgVars []string, cmd strslice.S + // + // Set the default command to run in the container (which may be empty). + // Argument handling is the same as RUN. +-// + func dispatchCmd(d dispatchRequest, c *instructions.CmdCommand) error { + runConfig := d.state.runConfig + cmd, argsEscaped := resolveCmdLine(c.ShellDependantCmdLine, runConfig, d.state.operatingSystem, c.Name(), c.String()) +@@ -473,7 +465,6 @@ func dispatchCmd(d dispatchRequest, c *instructions.CmdCommand) error { + // + // Set the default healthcheck command to run in the container (which may be empty). + // Argument handling is the same as RUN. +-// + func dispatchHealthcheck(d dispatchRequest, c *instructions.HealthCheckCommand) error { + runConfig := d.state.runConfig + if runConfig.Healthcheck != nil { +@@ -493,7 +484,6 @@ func dispatchHealthcheck(d dispatchRequest, c *instructions.HealthCheckCommand) + // + // Handles command processing similar to CMD and RUN, only req.runConfig.Entrypoint + // is initialized at newBuilder time instead of through argument parsing. +-// + func dispatchEntrypoint(d dispatchRequest, c *instructions.EntrypointCommand) error { + runConfig := d.state.runConfig + cmd, argsEscaped := resolveCmdLine(c.ShellDependantCmdLine, runConfig, d.state.operatingSystem, c.Name(), c.String()) +@@ -523,7 +513,6 @@ func dispatchEntrypoint(d dispatchRequest, c *instructions.EntrypointCommand) er + // + // Expose ports for links and port mappings. This all ends up in + // req.runConfig.ExposedPorts for runconfig. +-// + func dispatchExpose(d dispatchRequest, c *instructions.ExposeCommand, envs []string) error { + // custom multi word expansion + // expose $FOO with FOO="80 443" is expanded as EXPOSE [80,443]. This is the only command supporting word to words expansion +@@ -557,7 +546,6 @@ func dispatchExpose(d dispatchRequest, c *instructions.ExposeCommand, envs []str + // + // Set the user to 'foo' for future commands and when running the + // ENTRYPOINT/CMD at container run time. +-// + func dispatchUser(d dispatchRequest, c *instructions.UserCommand) error { + d.state.runConfig.User = c.User + return d.builder.commit(d.state, fmt.Sprintf("USER %v", c.User)) +@@ -566,7 +554,6 @@ func dispatchUser(d dispatchRequest, c *instructions.UserCommand) error { + // VOLUME /foo + // + // Expose the volume /foo for use. Will also accept the JSON array form. +-// + func dispatchVolume(d dispatchRequest, c *instructions.VolumeCommand) error { + if d.state.runConfig.Volumes == nil { + d.state.runConfig.Volumes = map[string]struct{}{} +diff --git a/builder/remotecontext/remote.go b/builder/remotecontext/remote.go +index 6eeadf521d..8f09ed0997 100644 +--- a/builder/remotecontext/remote.go ++++ b/builder/remotecontext/remote.go +@@ -80,10 +80,10 @@ func GetWithStatusError(address string) (resp *http.Response, err error) { + // inspectResponse looks into the http response data at r to determine whether its + // content-type is on the list of acceptable content types for remote build contexts. + // This function returns: +-// - a string representation of the detected content-type +-// - an io.Reader for the response body +-// - an error value which will be non-nil either when something goes wrong while +-// reading bytes from r or when the detected content-type is not acceptable. ++// - a string representation of the detected content-type ++// - an io.Reader for the response body ++// - an error value which will be non-nil either when something goes wrong while ++// reading bytes from r or when the detected content-type is not acceptable. + func inspectResponse(ct string, r io.Reader, clen int64) (string, io.Reader, error) { + plen := clen + if plen <= 0 || plen > maxPreambleLength { +diff --git a/client/client.go b/client/client.go +index 9b2b2eaeb8..0d3614d5db 100644 +--- a/client/client.go ++++ b/client/client.go +@@ -4,7 +4,7 @@ Package client is a Go client for the Docker Engine API. + For more information about the Engine API, see the documentation: + https://docs.docker.com/engine/api/ + +-Usage ++# Usage + + You use the library by creating a client object and calling methods on it. The + client can be created either from environment variables with NewClientWithOpts(client.FromEnv), +@@ -37,7 +37,6 @@ For example, to list running containers (the equivalent of "docker ps"): + fmt.Printf("%s %s\n", container.ID[:10], container.Image) + } + } +- + */ + package client // import "github.com/docker/docker/client" + +diff --git a/client/container_attach.go b/client/container_attach.go +index 88ba1ef639..3becefba08 100644 +--- a/client/container_attach.go ++++ b/client/container_attach.go +@@ -22,7 +22,7 @@ import ( + // multiplexed. + // The format of the multiplexed stream is as follows: + // +-// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} ++// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} + // + // STREAM_TYPE can be 1 for stdout and 2 for stderr + // +diff --git a/client/container_logs.go b/client/container_logs.go +index 5b6541f035..add852a833 100644 +--- a/client/container_logs.go ++++ b/client/container_logs.go +@@ -24,7 +24,7 @@ import ( + // multiplexed. + // The format of the multiplexed stream is as follows: + // +-// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} ++// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} + // + // STREAM_TYPE can be 1 for stdout and 2 for stderr + // +diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go +index bb710f6001..cea30cb313 100644 +--- a/cmd/dockerd/daemon.go ++++ b/cmd/dockerd/daemon.go +@@ -594,7 +594,7 @@ func newAPIServerConfig(cli *DaemonCli) (*apiserver.Config, error) { + + // checkTLSAuthOK checks basically for an explicitly disabled TLS/TLSVerify + // Going forward we do not want to support a scenario where dockerd listens +-// on TCP without either TLS client auth (or an explicit opt-in to disable it) ++// on TCP without either TLS client auth (or an explicit opt-in to disable it) + func checkTLSAuthOK(c *config.Config) bool { + if c.TLS == nil { + // Either TLS is enabled by default, in which case TLS verification should be enabled by default, or explicitly disabled +diff --git a/container/container.go b/container/container.go +index e96f087c55..b082a2677c 100644 +--- a/container/container.go ++++ b/container/container.go +@@ -300,10 +300,11 @@ func (container *Container) SetupWorkingDirectory(rootIdentity idtools.Identity) + // particular path inside the container as though you were a process in that + // container. + // +-// NOTE: The returned path is *only* safely scoped inside the container's BaseFS +-// if no component of the returned path changes (such as a component +-// symlinking to a different path) between using this method and using the +-// path. See symlink.FollowSymlinkInScope for more details. ++// # NOTE ++// The returned path is *only* safely scoped inside the container's BaseFS ++// if no component of the returned path changes (such as a component ++// symlinking to a different path) between using this method and using the ++// path. See symlink.FollowSymlinkInScope for more details. + func (container *Container) GetResourcePath(path string) (string, error) { + if container.BaseFS == nil { + return "", errors.New("GetResourcePath: BaseFS of container " + container.ID + " is unexpectedly nil") +@@ -329,10 +330,11 @@ func (container *Container) GetResourcePath(path string) (string, error) { + // Only use this method to safely access the container's `container.json` or + // other metadata files. If in doubt, use container.GetResourcePath. + // +-// NOTE: The returned path is *only* safely scoped inside the container's root +-// if no component of the returned path changes (such as a component +-// symlinking to a different path) between using this method and using the +-// path. See symlink.FollowSymlinkInScope for more details. ++// # NOTE ++// The returned path is *only* safely scoped inside the container's root ++// if no component of the returned path changes (such as a component ++// symlinking to a different path) between using this method and using the ++// path. See symlink.FollowSymlinkInScope for more details. + func (container *Container) GetRootResourcePath(path string) (string, error) { + // IMPORTANT - These are paths on the OS where the daemon is running, hence + // any filepath operations must be done in an OS agnostic way. +diff --git a/daemon/cluster/listen_addr.go b/daemon/cluster/listen_addr.go +index ca49a93568..06d2381645 100644 +--- a/daemon/cluster/listen_addr.go ++++ b/daemon/cluster/listen_addr.go +@@ -205,9 +205,9 @@ func resolveInterfaceAddr(specifiedInterface string) (net.IP, error) { + } + + // resolveInputIPAddr tries to resolve the IP address from the string passed as input +-// - tries to match the string as an interface name, if so returns the IP address associated with it +-// - on failure of previous step tries to parse the string as an IP address itself +-// if succeeds returns the IP address ++// - tries to match the string as an interface name, if so returns the IP address associated with it ++// - on failure of previous step tries to parse the string as an IP address itself ++// if succeeds returns the IP address + func resolveInputIPAddr(input string, isUnspecifiedValid bool) (net.IP, error) { + // Try to see if it is an interface name + interfaceAddr, err := resolveInterfaceAddr(input) +diff --git a/daemon/container.go b/daemon/container.go +index 5912f26b62..205e6b5d0f 100644 +--- a/daemon/container.go ++++ b/daemon/container.go +@@ -30,11 +30,11 @@ import ( + + // GetContainer looks for a container using the provided information, which could be + // one of the following inputs from the caller: +-// - A full container ID, which will exact match a container in daemon's list +-// - A container name, which will only exact match via the GetByName() function +-// - A partial container ID prefix (e.g. short ID) of any length that is +-// unique enough to only return a single container object +-// If none of these searches succeed, an error is returned ++// - A full container ID, which will exact match a container in daemon's list ++// - A container name, which will only exact match via the GetByName() function ++// - A partial container ID prefix (e.g. short ID) of any length that is ++// unique enough to only return a single container object ++// If none of these searches succeed, an error is returned + func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) { + if len(prefixOrName) == 0 { + return nil, errors.WithStack(invalidIdentifier(prefixOrName)) +diff --git a/daemon/content.go b/daemon/content.go +index 7afecb2308..eafa81829b 100644 +--- a/daemon/content.go ++++ b/daemon/content.go +@@ -63,7 +63,8 @@ func (cp namespacedContent) Info(ctx context.Context, dgst digest.Digest) (conte + // If one or more fieldpaths are provided, only those + // fields will be updated. + // Mutable fields: +-// labels.* ++// ++// labels.* + func (cp namespacedContent) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) { + return cp.provider.Update(withDefaultNamespace(ctx, cp.ns), info, fieldpaths...) + } +diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go +index 2ec54d7bbc..509a248489 100644 +--- a/daemon/daemon_unix.go ++++ b/daemon/daemon_unix.go +@@ -1073,15 +1073,16 @@ func setupInitLayer(idMapping *idtools.IdentityMapping) func(containerfs.Contain + } + + // Parse the remapped root (user namespace) option, which can be one of: +-// username - valid username from /etc/passwd +-// username:groupname - valid username; valid groupname from /etc/group +-// uid - 32-bit unsigned int valid Linux UID value +-// uid:gid - uid value; 32-bit unsigned int Linux GID value + // +-// If no groupname is specified, and a username is specified, an attempt +-// will be made to lookup a gid for that username as a groupname ++// - username - valid username from /etc/passwd ++// - username:groupname - valid username; valid groupname from /etc/group ++// - uid - 32-bit unsigned int valid Linux UID value ++// - uid:gid - uid value; 32-bit unsigned int Linux GID value + // +-// If names are used, they are verified to exist in passwd/group ++// If no groupname is specified, and a username is specified, an attempt ++// will be made to lookup a gid for that username as a groupname ++// ++// If names are used, they are verified to exist in passwd/group + func parseRemappedRoot(usergrp string) (string, string, error) { + + var ( +diff --git a/daemon/graphdriver/fsdiff.go b/daemon/graphdriver/fsdiff.go +index f06caedb92..3f78c0d1b1 100644 +--- a/daemon/graphdriver/fsdiff.go ++++ b/daemon/graphdriver/fsdiff.go +@@ -31,10 +31,11 @@ type NaiveDiffDriver struct { + // NewNaiveDiffDriver returns a fully functional driver that wraps the + // given ProtoDriver and adds the capability of the following methods which + // it may or may not support on its own: +-// Diff(id, parent string) (archive.Archive, error) +-// Changes(id, parent string) ([]archive.Change, error) +-// ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) +-// DiffSize(id, parent string) (size int64, err error) ++// ++// Diff(id, parent string) (archive.Archive, error) ++// Changes(id, parent string) ([]archive.Change, error) ++// ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) ++// DiffSize(id, parent string) (size int64, err error) + func NewNaiveDiffDriver(driver ProtoDriver, uidMaps, gidMaps []idtools.IDMap) Driver { + return &NaiveDiffDriver{ProtoDriver: driver, + uidMaps: uidMaps, +diff --git a/daemon/graphdriver/lcow/lcow_svm.go b/daemon/graphdriver/lcow/lcow_svm.go +index 67c82c783f..15d0a6230d 100644 +--- a/daemon/graphdriver/lcow/lcow_svm.go ++++ b/daemon/graphdriver/lcow/lcow_svm.go +@@ -62,12 +62,12 @@ type serviceVM struct { + } + + // add will add an id to the service vm map. There are three cases: +-// - entry doesn't exist: +-// - add id to map and return a new vm that the caller can manually configure+start +-// - entry does exist +-// - return vm in map and increment ref count +-// - entry does exist but the ref count is 0 +-// - return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop ++// - entry doesn't exist: ++// add id to map and return a new vm that the caller can manually configure+start ++// - entry does exist: ++// return vm in map and increment ref count ++// - entry does exist but the ref count is 0: ++// return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop + func (svmMap *serviceVMMap) add(id string) (svm *serviceVM, alreadyExists bool, err error) { + svmMap.Lock() + defer svmMap.Unlock() +@@ -95,12 +95,12 @@ func (svmMap *serviceVMMap) add(id string) (svm *serviceVM, alreadyExists bool, + } + + // get will get the service vm from the map. There are three cases: +-// - entry doesn't exist: +-// - return errVMUnknown +-// - entry does exist +-// - return vm with no error +-// - entry does exist but the ref count is 0 +-// - return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop ++// - entry doesn't exist: ++// return errVMUnknown ++// - entry does exist: ++// return vm with no error ++// - entry does exist but the ref count is 0: ++// return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop + func (svmMap *serviceVMMap) get(id string) (*serviceVM, error) { + svmMap.Lock() + defer svmMap.Unlock() +@@ -115,15 +115,15 @@ func (svmMap *serviceVMMap) get(id string) (*serviceVM, error) { + } + + // decrementRefCount decrements the ref count of the given ID from the map. There are four cases: +-// - entry doesn't exist: +-// - return errVMUnknown +-// - entry does exist but the ref count is 0 +-// - return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop +-// - entry does exist but ref count is 1 +-// - return vm and set lastRef to true. The caller can then stop the vm, delete the id from this map +-// - and execute svm.signalStopFinished to signal the threads that the svm has been terminated. +-// - entry does exist and ref count > 1 +-// - just reduce ref count and return svm ++// - entry doesn't exist: ++// return errVMUnknown ++// - entry does exist but the ref count is 0: ++// return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop ++// - entry does exist but ref count is 1: ++// return vm and set lastRef to true. The caller can then stop the vm, delete the id from this map ++// and execute svm.signalStopFinished to signal the threads that the svm has been terminated. ++// - entry does exist and ref count > 1: ++// just reduce ref count and return svm + func (svmMap *serviceVMMap) decrementRefCount(id string) (_ *serviceVM, lastRef bool, _ error) { + svmMap.Lock() + defer svmMap.Unlock() +diff --git a/daemon/images/image.go b/daemon/images/image.go +index 8b96604781..436a8189ac 100644 +--- a/daemon/images/image.go ++++ b/daemon/images/image.go +@@ -219,7 +219,7 @@ func (i *ImageService) GetImage(refOrID string, platform *specs.Platform) (retIm + } + + // OnlyPlatformWithFallback uses `platforms.Only` with a fallback to handle the case where the platform +-// being matched does not have a CPU variant. ++// being matched does not have a CPU variant. + // + // The reason for this is that CPU variant is not even if the official image config spec as of this writing. + // See: https://github.com/opencontainers/image-spec/pull/809 +diff --git a/daemon/images/image_commit.go b/daemon/images/image_commit.go +index 4caba9f27b..bffd38f2b5 100644 +--- a/daemon/images/image_commit.go ++++ b/daemon/images/image_commit.go +@@ -109,9 +109,9 @@ func exportContainerRw(layerStore layer.Store, id, mountLabel string) (arch io.R + // the build. + // + // This method is different from CreateImageFromContainer: +-// * it doesn't attempt to validate container state +-// * it doesn't send a commit action to metrics +-// * it doesn't log a container commit event ++// - it doesn't attempt to validate container state ++// - it doesn't send a commit action to metrics ++// - it doesn't log a container commit event + // + // This is a temporary shim. Should be removed when builder stops using commit. + func (i *ImageService) CommitBuildStep(c backend.CommitConfig) (image.ID, error) { +diff --git a/daemon/images/image_delete.go b/daemon/images/image_delete.go +index c4acf89999..b145910ade 100644 +--- a/daemon/images/image_delete.go ++++ b/daemon/images/image_delete.go +@@ -45,13 +45,13 @@ const ( + // are divided into two categories grouped by their severity: + // + // Hard Conflict: +-// - a pull or build using the image. +-// - any descendant image. +-// - any running container using the image. ++// - a pull or build using the image. ++// - any descendant image. ++// - any running container using the image. + // + // Soft Conflict: +-// - any stopped container using the image. +-// - any repository tag or digest references to the image. ++// - any stopped container using the image. ++// - any repository tag or digest references to the image. + // + // The image cannot be removed if there are any hard conflicts and can be + // removed if there are soft conflicts only if force is true. +@@ -59,7 +59,6 @@ const ( + // If prune is true, ancestor images will each attempt to be deleted quietly, + // meaning any delete conflicts will cause the image to not be deleted and the + // conflict will not be reported. +-// + func (i *ImageService) ImageDelete(imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) { + start := time.Now() + records := []types.ImageDeleteResponseItem{} +diff --git a/daemon/info_unix.go b/daemon/info_unix.go +index be554844d0..d88c6fb21b 100644 +--- a/daemon/info_unix.go ++++ b/daemon/info_unix.go +@@ -249,7 +249,7 @@ func getBackingFs(v *types.Info) string { + // + // Output example from `docker-init --version`: + // +-// tini version 0.18.0 - git.fec3683 ++// tini version 0.18.0 - git.fec3683 + func parseInitVersion(v string) (version string, commit string, err error) { + parts := strings.Split(v, " - ") + +@@ -274,9 +274,9 @@ func parseInitVersion(v string) (version string, commit string, err error) { + // + // Output example from `runc --version`: + // +-// runc version 1.0.0-rc5+dev +-// commit: 69663f0bd4b60df09991c08812a60108003fa340 +-// spec: 1.0.0 ++// runc version 1.0.0-rc5+dev ++// commit: 69663f0bd4b60df09991c08812a60108003fa340 ++// spec: 1.0.0 + func parseRuntimeVersion(v string) (runtime string, version string, commit string, err error) { + lines := strings.Split(strings.TrimSpace(v), "\n") + for _, line := range lines { +diff --git a/daemon/top_windows.go b/daemon/top_windows.go +index 010b426d3f..eaaad4f771 100644 +--- a/daemon/top_windows.go ++++ b/daemon/top_windows.go +@@ -11,19 +11,20 @@ import ( + ) + + // ContainerTop handles `docker top` client requests. ++// + // Future considerations: +-// -- Windows users are far more familiar with CPU% total. +-// Further, users on Windows rarely see user/kernel CPU stats split. +-// The kernel returns everything in terms of 100ns. To obtain +-// CPU%, we could do something like docker stats does which takes two +-// samples, subtract the difference and do the maths. Unfortunately this +-// would slow the stat call down and require two kernel calls. So instead, +-// we do something similar to linux and display the CPU as combined HH:MM:SS.mmm. +-// -- Perhaps we could add an argument to display "raw" stats +-// -- "Memory" is an extremely overloaded term in Windows. Hence we do what +-// task manager does and use the private working set as the memory counter. +-// We could return more info for those who really understand how memory +-// management works in Windows if we introduced a "raw" stats (above). ++// - Windows users are far more familiar with CPU% total. ++// Further, users on Windows rarely see user/kernel CPU stats split. ++// The kernel returns everything in terms of 100ns. To obtain ++// CPU%, we could do something like docker stats does which takes two ++// samples, subtract the difference and do the maths. Unfortunately this ++// would slow the stat call down and require two kernel calls. So instead, ++// we do something similar to linux and display the CPU as combined HH:MM:SS.mmm. ++// - Perhaps we could add an argument to display "raw" stats ++// - "Memory" is an extremely overloaded term in Windows. Hence we do what ++// task manager does and use the private working set as the memory counter. ++// We could return more info for those who really understand how memory ++// management works in Windows if we introduced a "raw" stats (above). + func (daemon *Daemon) ContainerTop(name string, psArgs string) (*containertypes.ContainerTopOKBody, error) { + // It's not at all an equivalent to linux 'ps' on Windows + if psArgs != "" { +diff --git a/dockerversion/useragent.go b/dockerversion/useragent.go +index afbdcd8584..d08b391268 100644 +--- a/dockerversion/useragent.go ++++ b/dockerversion/useragent.go +@@ -14,7 +14,8 @@ type UAStringKey struct{} + + // DockerUserAgent is the User-Agent the Docker client uses to identify itself. + // In accordance with RFC 7231 (5.5.3) is of the form: +-// [docker client's UA] UpstreamClient([upstream client's UA]) ++// ++// [docker client's UA] UpstreamClient([upstream client's UA]) + func DockerUserAgent(ctx context.Context) string { + httpVersion := make([]useragent.VersionInfo, 0, 6) + httpVersion = append(httpVersion, useragent.VersionInfo{Name: "docker", Version: Version}) +@@ -68,7 +69,8 @@ func escapeStr(s string, charsToEscape string) string { + + // insertUpstreamUserAgent adds the upstream client useragent to create a user-agent + // string of the form: +-// $dockerUA UpstreamClient($upstreamUA) ++// ++// $dockerUA UpstreamClient($upstreamUA) + func insertUpstreamUserAgent(upstreamUA string, dockerUA string) string { + charsToEscape := `();\` + upstreamUAEscaped := escapeStr(upstreamUA, charsToEscape) +diff --git a/hack/make/.resources-windows/resources.go b/hack/make/.resources-windows/resources.go +index 3ade4eadd9..ceabca2344 100644 +--- a/hack/make/.resources-windows/resources.go ++++ b/hack/make/.resources-windows/resources.go +@@ -1,11 +1,10 @@ + /* +- + Package winresources is used to embed Windows resources into dockerd.exe. + These resources are used to provide + +- * Version information +- * An icon +- * A Windows manifest declaring Windows version support ++ - Version information ++ - An icon ++ - A Windows manifest declaring Windows version support + + The resource object files are generated in hack/make/.go-autogen from + source files in hack/make/.resources-windows. This occurs automatically +@@ -13,6 +12,5 @@ when you run hack/make.sh. + + These object files are picked up automatically by go build when this package + is included. +- + */ + package winresources +diff --git a/integration-cli/docker_cli_cp_from_container_test.go b/integration-cli/docker_cli_cp_from_container_test.go +index a357489280..e2ce82bb37 100644 +--- a/integration-cli/docker_cli_cp_from_container_test.go ++++ b/integration-cli/docker_cli_cp_from_container_test.go +@@ -93,9 +93,10 @@ func (s *DockerSuite) TestCpFromSymlinkDestination(c *testing.T) { + // J | yes | yes | yes | yes | - | copy dir contents + // + +-// A. SRC specifies a file and DST (no trailing path separator) doesn't +-// exist. This should create a file with the name DST and copy the +-// contents of the source file into it. ++// A. SRC specifies a file and DST (no trailing path separator) doesn't exist. ++// ++// This should create a file with the name DST and copy the contents of the ++// source file into it. + func (s *DockerSuite) TestCpFromCaseA(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -112,9 +113,10 @@ func (s *DockerSuite) TestCpFromCaseA(c *testing.T) { + assert.NilError(c, fileContentEquals(c, dstPath, "file1\n")) + } + +-// B. SRC specifies a file and DST (with trailing path separator) doesn't +-// exist. This should cause an error because the copy operation cannot +-// create a directory when copying a single file. ++// B. SRC specifies a file and DST (with trailing path separator) doesn't exist. ++// ++// This should cause an error because the copy operation cannot create a directory ++// when copying a single file. + func (s *DockerSuite) TestCpFromCaseB(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{addContent: true}) +@@ -130,8 +132,9 @@ func (s *DockerSuite) TestCpFromCaseB(c *testing.T) { + assert.Assert(c, isCpDirNotExist(err), "expected DirNotExists error, but got %T: %s", err, err) + } + +-// C. SRC specifies a file and DST exists as a file. This should overwrite +-// the file at DST with the contents of the source file. ++// C. SRC specifies a file and DST exists as a file. ++// ++// This should overwrite the file at DST with the contents of the source file. + func (s *DockerSuite) TestCpFromCaseC(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -152,9 +155,10 @@ func (s *DockerSuite) TestCpFromCaseC(c *testing.T) { + assert.NilError(c, fileContentEquals(c, dstPath, "file1\n")) + } + +-// D. SRC specifies a file and DST exists as a directory. This should place +-// a copy of the source file inside it using the basename from SRC. Ensure +-// this works whether DST has a trailing path separator or not. ++// D. SRC specifies a file and DST exists as a directory. ++// ++// This should place a copy of the source file inside it using the basename from ++// SRC. Ensure this works whether DST has a trailing path separator or not. + func (s *DockerSuite) TestCpFromCaseD(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{addContent: true}) +@@ -186,10 +190,11 @@ func (s *DockerSuite) TestCpFromCaseD(c *testing.T) { + assert.NilError(c, fileContentEquals(c, dstPath, "file1\n")) + } + +-// E. SRC specifies a directory and DST does not exist. This should create a +-// directory at DST and copy the contents of the SRC directory into the DST +-// directory. Ensure this works whether DST has a trailing path separator or +-// not. ++// E. SRC specifies a directory and DST does not exist. ++// ++// This should create a directory at DST and copy the contents of the SRC directory ++// into the DST directory. Ensure this works whether DST has a trailing path ++// separator or not. + func (s *DockerSuite) TestCpFromCaseE(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{addContent: true}) +@@ -214,8 +219,10 @@ func (s *DockerSuite) TestCpFromCaseE(c *testing.T) { + assert.NilError(c, fileContentEquals(c, dstPath, "file1-1\n")) + } + +-// F. SRC specifies a directory and DST exists as a file. This should cause an +-// error as it is not possible to overwrite a file with a directory. ++// F. SRC specifies a directory and DST exists as a file. ++// ++// This should cause an error as it is not possible to overwrite a file with a ++// directory. + func (s *DockerSuite) TestCpFromCaseF(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -235,9 +242,10 @@ func (s *DockerSuite) TestCpFromCaseF(c *testing.T) { + assert.Assert(c, isCpCannotCopyDir(err), "expected ErrCannotCopyDir error, but got %T: %s", err, err) + } + +-// G. SRC specifies a directory and DST exists as a directory. This should copy +-// the SRC directory and all its contents to the DST directory. Ensure this +-// works whether DST has a trailing path separator or not. ++// G. SRC specifies a directory and DST exists as a directory. ++// ++// This should copy the SRC directory and all its contents to the DST directory. ++// Ensure this works whether DST has a trailing path separator or not. + func (s *DockerSuite) TestCpFromCaseG(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -268,10 +276,11 @@ func (s *DockerSuite) TestCpFromCaseG(c *testing.T) { + assert.NilError(c, fileContentEquals(c, dstPath, "file1-1\n")) + } + +-// H. SRC specifies a directory's contents only and DST does not exist. This +-// should create a directory at DST and copy the contents of the SRC +-// directory (but not the directory itself) into the DST directory. Ensure +-// this works whether DST has a trailing path separator or not. ++// H. SRC specifies a directory's contents only and DST does not exist. ++// ++// This should create a directory at DST and copy the contents of the SRC ++// directory (but not the directory itself) into the DST directory. Ensure ++// this works whether DST has a trailing path separator or not. + func (s *DockerSuite) TestCpFromCaseH(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{addContent: true}) +@@ -296,9 +305,10 @@ func (s *DockerSuite) TestCpFromCaseH(c *testing.T) { + assert.NilError(c, fileContentEquals(c, dstPath, "file1-1\n")) + } + +-// I. SRC specifies a directory's contents only and DST exists as a file. This +-// should cause an error as it is not possible to overwrite a file with a +-// directory. ++// I. SRC specifies a directory's contents only and DST exists as a file. ++// ++// This should cause an error as it is not possible to overwrite a file with a ++// directory. + func (s *DockerSuite) TestCpFromCaseI(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -319,9 +329,10 @@ func (s *DockerSuite) TestCpFromCaseI(c *testing.T) { + } + + // J. SRC specifies a directory's contents only and DST exists as a directory. +-// This should copy the contents of the SRC directory (but not the directory +-// itself) into the DST directory. Ensure this works whether DST has a +-// trailing path separator or not. ++// ++// This should copy the contents of the SRC directory (but not the directory ++// itself) into the DST directory. Ensure this works whether DST has a ++// trailing path separator or not. + func (s *DockerSuite) TestCpFromCaseJ(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +diff --git a/integration-cli/docker_cli_cp_to_container_test.go b/integration-cli/docker_cli_cp_to_container_test.go +index 6f28077f92..8c2815a9fb 100644 +--- a/integration-cli/docker_cli_cp_to_container_test.go ++++ b/integration-cli/docker_cli_cp_to_container_test.go +@@ -97,9 +97,10 @@ func (s *DockerSuite) TestCpToSymlinkDestination(c *testing.T) { + // J | yes | yes | yes | yes | - | copy dir contents + // + +-// A. SRC specifies a file and DST (no trailing path separator) doesn't +-// exist. This should create a file with the name DST and copy the +-// contents of the source file into it. ++// A. SRC specifies a file and DST (no trailing path separator) doesn't exist. ++// ++// This should create a file with the name DST and copy the contents of the ++// source file into it. + func (s *DockerSuite) TestCpToCaseA(c *testing.T) { + containerID := makeTestContainer(c, testContainerOptions{ + workDir: "/root", command: makeCatFileCommand("itWorks.txt"), +@@ -117,9 +118,10 @@ func (s *DockerSuite) TestCpToCaseA(c *testing.T) { + assert.NilError(c, containerStartOutputEquals(c, containerID, "file1\n")) + } + +-// B. SRC specifies a file and DST (with trailing path separator) doesn't +-// exist. This should cause an error because the copy operation cannot +-// create a directory when copying a single file. ++// B. SRC specifies a file and DST (with trailing path separator) doesn't exist. ++// ++// This should cause an error because the copy operation cannot create a ++// directory when copying a single file. + func (s *DockerSuite) TestCpToCaseB(c *testing.T) { + containerID := makeTestContainer(c, testContainerOptions{ + command: makeCatFileCommand("testDir/file1"), +@@ -138,8 +140,9 @@ func (s *DockerSuite) TestCpToCaseB(c *testing.T) { + assert.Assert(c, isCpDirNotExist(err), "expected DirNotExists error, but got %T: %s", err, err) + } + +-// C. SRC specifies a file and DST exists as a file. This should overwrite +-// the file at DST with the contents of the source file. ++// C. SRC specifies a file and DST exists as a file. ++// ++// This should overwrite the file at DST with the contents of the source file. + func (s *DockerSuite) TestCpToCaseC(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -161,9 +164,10 @@ func (s *DockerSuite) TestCpToCaseC(c *testing.T) { + assert.NilError(c, containerStartOutputEquals(c, containerID, "file1\n"), "Should now contain file1's contents") + } + +-// D. SRC specifies a file and DST exists as a directory. This should place +-// a copy of the source file inside it using the basename from SRC. Ensure +-// this works whether DST has a trailing path separator or not. ++// D. SRC specifies a file and DST exists as a directory. ++// ++// This should place a copy of the source file inside it using the basename from ++// SRC. Ensure this works whether DST has a trailing path separator or not. + func (s *DockerSuite) TestCpToCaseD(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -198,10 +202,11 @@ func (s *DockerSuite) TestCpToCaseD(c *testing.T) { + assert.NilError(c, containerStartOutputEquals(c, containerID, "file1\n"), "Should now contain file1's contents") + } + +-// E. SRC specifies a directory and DST does not exist. This should create a +-// directory at DST and copy the contents of the SRC directory into the DST +-// directory. Ensure this works whether DST has a trailing path separator or +-// not. ++// E. SRC specifies a directory and DST does not exist. ++// ++// This should create a directory at DST and copy the contents of the SRC ++// directory into the DST directory. Ensure this works whether DST has a ++// trailing path separator or not. + func (s *DockerSuite) TestCpToCaseE(c *testing.T) { + containerID := makeTestContainer(c, testContainerOptions{ + command: makeCatFileCommand("/testDir/file1-1"), +@@ -231,8 +236,10 @@ func (s *DockerSuite) TestCpToCaseE(c *testing.T) { + assert.NilError(c, containerStartOutputEquals(c, containerID, "file1-1\n"), "Should now contain file1-1's contents") + } + +-// F. SRC specifies a directory and DST exists as a file. This should cause an +-// error as it is not possible to overwrite a file with a directory. ++// F. SRC specifies a directory and DST exists as a file. ++// ++// This should cause an error as it is not possible to overwrite a file with a ++// directory. + func (s *DockerSuite) TestCpToCaseF(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -252,9 +259,10 @@ func (s *DockerSuite) TestCpToCaseF(c *testing.T) { + assert.Assert(c, isCpCannotCopyDir(err), "expected ErrCannotCopyDir error, but got %T: %s", err, err) + } + +-// G. SRC specifies a directory and DST exists as a directory. This should copy +-// the SRC directory and all its contents to the DST directory. Ensure this +-// works whether DST has a trailing path separator or not. ++// G. SRC specifies a directory and DST exists as a directory. ++// ++// This should copy the SRC directory and all its contents to the DST directory. ++// Ensure this works whether DST has a trailing path separator or not. + func (s *DockerSuite) TestCpToCaseG(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -289,10 +297,11 @@ func (s *DockerSuite) TestCpToCaseG(c *testing.T) { + assert.NilError(c, containerStartOutputEquals(c, containerID, "file1-1\n"), "Should now contain file1-1's contents") + } + +-// H. SRC specifies a directory's contents only and DST does not exist. This +-// should create a directory at DST and copy the contents of the SRC +-// directory (but not the directory itself) into the DST directory. Ensure +-// this works whether DST has a trailing path separator or not. ++// H. SRC specifies a directory's contents only and DST does not exist. ++// ++// This should create a directory at DST and copy the contents of the SRC ++// directory (but not the directory itself) into the DST directory. Ensure ++// this works whether DST has a trailing path separator or not. + func (s *DockerSuite) TestCpToCaseH(c *testing.T) { + containerID := makeTestContainer(c, testContainerOptions{ + command: makeCatFileCommand("/testDir/file1-1"), +@@ -322,9 +331,10 @@ func (s *DockerSuite) TestCpToCaseH(c *testing.T) { + assert.NilError(c, containerStartOutputEquals(c, containerID, "file1-1\n"), "Should now contain file1-1's contents") + } + +-// I. SRC specifies a directory's contents only and DST exists as a file. This +-// should cause an error as it is not possible to overwrite a file with a +-// directory. ++// I. SRC specifies a directory's contents only and DST exists as a file. ++// ++// This should cause an error as it is not possible to overwrite a file with a ++// directory. + func (s *DockerSuite) TestCpToCaseI(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +@@ -345,9 +355,10 @@ func (s *DockerSuite) TestCpToCaseI(c *testing.T) { + } + + // J. SRC specifies a directory's contents only and DST exists as a directory. +-// This should copy the contents of the SRC directory (but not the directory +-// itself) into the DST directory. Ensure this works whether DST has a +-// trailing path separator or not. ++// ++// This should copy the contents of the SRC directory (but not the directory ++// itself) into the DST directory. Ensure this works whether DST has a ++// trailing path separator or not. + func (s *DockerSuite) TestCpToCaseJ(c *testing.T) { + testRequires(c, DaemonIsLinux) + containerID := makeTestContainer(c, testContainerOptions{ +diff --git a/integration-cli/docker_cli_external_volume_driver_test.go b/integration-cli/docker_cli_external_volume_driver_test.go +index 0428b7cc20..8106cd1529 100644 +--- a/integration-cli/docker_cli_external_volume_driver_test.go ++++ b/integration-cli/docker_cli_external_volume_driver_test.go +@@ -505,8 +505,7 @@ func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverGetEmptyResponse(c * + + // Ensure only cached paths are used in volume list to prevent N+1 calls to `VolumeDriver.Path` + // +-// TODO(@cpuguy83): This test is testing internal implementation. In all the cases here, there may not even be a path +-// available because the volume is not even mounted. Consider removing this test. ++// TODO(@cpuguy83): This test is testing internal implementation. In all the cases here, there may not even be a path available because the volume is not even mounted. Consider removing this test. + func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverPathCalls(c *testing.T) { + s.d.Start(c) + assert.Equal(c, s.ec.paths, 0) +diff --git a/integration/container/ipcmode_linux_test.go b/integration/container/ipcmode_linux_test.go +index 030ec90179..a51b7282c8 100644 +--- a/integration/container/ipcmode_linux_test.go ++++ b/integration/container/ipcmode_linux_test.go +@@ -26,9 +26,9 @@ import ( + // + // The format of /proc/self/mountinfo is like: + // +-// 29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw +-// ^^^^\ +-// - this is the minor:major we look for ++// 29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw ++// ^^^^\ ++// - this is the minor:major we look for + func testIpcCheckDevExists(mm string) (bool, error) { + f, err := os.Open("/proc/self/mountinfo") + if err != nil { +diff --git a/integration/image/pull_test.go b/integration/image/pull_test.go +index 96def69395..bf63045a61 100644 +--- a/integration/image/pull_test.go ++++ b/integration/image/pull_test.go +@@ -115,7 +115,7 @@ func createTestImage(ctx context.Context, t testing.TB, store content.Store) ima + } + + // Make sure that pulling by an already cached digest but for a different ref (that should not have that digest) +-// verifies with the remote that the digest exists in that repo. ++// verifies with the remote that the digest exists in that repo. + func TestImagePullStoredfDigestForOtherRepo(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") + skip.If(t, testEnv.OSType == "windows", "We don't run a test registry on Windows") +diff --git a/integration/internal/container/exec.go b/integration/internal/container/exec.go +index dfd46a2436..918506d4e3 100644 +--- a/integration/internal/container/exec.go ++++ b/integration/internal/container/exec.go +@@ -33,8 +33,8 @@ func (res *ExecResult) Combined() string { + + // Exec executes a command inside a container, returning the result + // containing stdout, stderr, and exit code. Note: +-// - this is a synchronous operation; +-// - cmd stdin is closed. ++// - this is a synchronous operation; ++// - cmd stdin is closed. + func Exec(ctx context.Context, cli client.APIClient, id string, cmd []string) (ExecResult, error) { + // prepare exec + execConfig := types.ExecConfig{ +diff --git a/integration/service/create_test.go b/integration/service/create_test.go +index 8335f894b8..0cba172d7d 100644 +--- a/integration/service/create_test.go ++++ b/integration/service/create_test.go +@@ -363,7 +363,7 @@ func TestCreateServiceConfigFileMode(t *testing.T) { + // + // To test this, we're going to create a service with the sysctl option + // +-// {"net.ipv4.ip_nonlocal_bind": "0"} ++// {"net.ipv4.ip_nonlocal_bind": "0"} + // + // We'll get the service's tasks to get the container ID, and then we'll + // inspect the container. If the output of the container inspect contains the +@@ -458,7 +458,7 @@ func TestCreateServiceSysctls(t *testing.T) { + // + // To test this, we're going to create a service with the capabilities option + // +-// []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"} ++// []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"} + // + // We'll get the service's tasks to get the container ID, and then we'll + // inspect the container. If the output of the container inspect contains the +diff --git a/integration/system/cgroupdriver_systemd_test.go b/integration/system/cgroupdriver_systemd_test.go +index c1b998abae..4544edffc9 100644 +--- a/integration/system/cgroupdriver_systemd_test.go ++++ b/integration/system/cgroupdriver_systemd_test.go +@@ -26,7 +26,7 @@ func hasSystemd() bool { + + // TestCgroupDriverSystemdMemoryLimit checks that container + // memory limit can be set when using systemd cgroupdriver. +-// https://github.com/moby/moby/issues/35123 ++// https://github.com/moby/moby/issues/35123 + func TestCgroupDriverSystemdMemoryLimit(t *testing.T) { + skip.If(t, testEnv.DaemonInfo.OSType == "windows") + skip.If(t, !hasSystemd()) +diff --git a/libcontainerd/local/local_windows.go b/libcontainerd/local/local_windows.go +index ffdd12429a..0e9ef88ab2 100644 +--- a/libcontainerd/local/local_windows.go ++++ b/libcontainerd/local/local_windows.go +@@ -116,43 +116,43 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) { + // + // Isolation=Process example: + // +-// { +-// "SystemType": "Container", +-// "Name": "5e0055c814a6005b8e57ac59f9a522066e0af12b48b3c26a9416e23907698776", +-// "Owner": "docker", +-// "VolumePath": "\\\\\\\\?\\\\Volume{66d1ef4c-7a00-11e6-8948-00155ddbef9d}", +-// "IgnoreFlushesDuringBoot": true, +-// "LayerFolderPath": "C:\\\\control\\\\windowsfilter\\\\5e0055c814a6005b8e57ac59f9a522066e0af12b48b3c26a9416e23907698776", +-// "Layers": [{ +-// "ID": "18955d65-d45a-557b-bf1c-49d6dfefc526", +-// "Path": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c" +-// }], +-// "HostName": "5e0055c814a6", +-// "MappedDirectories": [], +-// "HvPartition": false, +-// "EndpointList": ["eef2649d-bb17-4d53-9937-295a8efe6f2c"], +-// } ++// { ++// "SystemType": "Container", ++// "Name": "5e0055c814a6005b8e57ac59f9a522066e0af12b48b3c26a9416e23907698776", ++// "Owner": "docker", ++// "VolumePath": "\\\\\\\\?\\\\Volume{66d1ef4c-7a00-11e6-8948-00155ddbef9d}", ++// "IgnoreFlushesDuringBoot": true, ++// "LayerFolderPath": "C:\\\\control\\\\windowsfilter\\\\5e0055c814a6005b8e57ac59f9a522066e0af12b48b3c26a9416e23907698776", ++// "Layers": [{ ++// "ID": "18955d65-d45a-557b-bf1c-49d6dfefc526", ++// "Path": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c" ++// }], ++// "HostName": "5e0055c814a6", ++// "MappedDirectories": [], ++// "HvPartition": false, ++// "EndpointList": ["eef2649d-bb17-4d53-9937-295a8efe6f2c"], ++// } + // + // Isolation=Hyper-V example: + // +-// { +-// "SystemType": "Container", +-// "Name": "475c2c58933b72687a88a441e7e0ca4bd72d76413c5f9d5031fee83b98f6045d", +-// "Owner": "docker", +-// "IgnoreFlushesDuringBoot": true, +-// "Layers": [{ +-// "ID": "18955d65-d45a-557b-bf1c-49d6dfefc526", +-// "Path": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c" +-// }], +-// "HostName": "475c2c58933b", +-// "MappedDirectories": [], +-// "HvPartition": true, +-// "EndpointList": ["e1bb1e61-d56f-405e-b75d-fd520cefa0cb"], +-// "DNSSearchList": "a.com,b.com,c.com", +-// "HvRuntime": { +-// "ImagePath": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c\\\\UtilityVM" +-// }, +-// } ++// { ++// "SystemType": "Container", ++// "Name": "475c2c58933b72687a88a441e7e0ca4bd72d76413c5f9d5031fee83b98f6045d", ++// "Owner": "docker", ++// "IgnoreFlushesDuringBoot": true, ++// "Layers": [{ ++// "ID": "18955d65-d45a-557b-bf1c-49d6dfefc526", ++// "Path": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c" ++// }], ++// "HostName": "475c2c58933b", ++// "MappedDirectories": [], ++// "HvPartition": true, ++// "EndpointList": ["e1bb1e61-d56f-405e-b75d-fd520cefa0cb"], ++// "DNSSearchList": "a.com,b.com,c.com", ++// "HvRuntime": { ++// "ImagePath": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c\\\\UtilityVM" ++// }, ++// } + func (c *client) Create(_ context.Context, id string, spec *specs.Spec, shim string, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error { + if ctr := c.getContainer(id); ctr != nil { + return errors.WithStack(errdefs.Conflict(errors.New("id already in use"))) +diff --git a/oci/oci.go b/oci/oci.go +index c64077da76..2021ec3538 100644 +--- a/oci/oci.go ++++ b/oci/oci.go +@@ -8,13 +8,14 @@ import ( + specs "github.com/opencontainers/runtime-spec/specs-go" + ) + +-// TODO verify if this regex is correct for "a" (all); the docs (https://github.com/torvalds/linux/blob/v5.10/Documentation/admin-guide/cgroup-v1/devices.rst) describe: +-// "'all' means it applies to all types and all major and minor numbers", and shows an example +-// that *only* passes `a` as value: `echo a > /sys/fs/cgroup/1/devices.allow, which would be +-// the "implicit" equivalent of "a *:* rwm". Source-code also looks to confirm this, and returns +-// early for "a" (all); https://github.com/torvalds/linux/blob/v5.10/security/device_cgroup.c#L614-L642 +-//nolint: gosimple +-var deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$") ++// TODO verify if this regex is correct for "a" (all); ++// ++// The docs (https://github.com/torvalds/linux/blob/v5.10/Documentation/admin-guide/cgroup-v1/devices.rst) describe: ++// "'all' means it applies to all types and all major and minor numbers", and shows an example ++// that *only* passes `a` as value: `echo a > /sys/fs/cgroup/1/devices.allow, which would be ++// the "implicit" equivalent of "a *:* rwm". Source-code also looks to confirm this, and returns ++// early for "a" (all); https://github.com/torvalds/linux/blob/v5.10/security/device_cgroup.c#L614-L642 ++var deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$") //nolint: gosimple + + // SetCapabilities sets the provided capabilities on the spec + // All capabilities are added if privileged is true. +diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go +index 2c18d8b03f..ade5f5396b 100644 +--- a/pkg/archive/archive.go ++++ b/pkg/archive/archive.go +@@ -1046,7 +1046,8 @@ loop: + // Untar reads a stream of bytes from `archive`, parses it as a tar archive, + // and unpacks it into the directory at `dest`. + // The archive may be compressed with one of the following algorithms: +-// identity (uncompressed), gzip, bzip2, xz. ++// identity (uncompressed), gzip, bzip2, xz. ++// + // FIXME: specify behavior when target path exists vs. doesn't exist. + func Untar(tarArchive io.Reader, dest string, options *TarOptions) error { + return untarHandler(tarArchive, dest, options, true) +diff --git a/pkg/archive/archive_linux_test.go b/pkg/archive/archive_linux_test.go +index e88e556d58..c2edb1ccba 100644 +--- a/pkg/archive/archive_linux_test.go ++++ b/pkg/archive/archive_linux_test.go +@@ -15,13 +15,14 @@ import ( + + // setupOverlayTestDir creates files in a directory with overlay whiteouts + // Tree layout +-// . +-// ├── d1 # opaque, 0700 +-// │   └── f1 # empty file, 0600 +-// ├── d2 # opaque, 0750 +-// │   └── f1 # empty file, 0660 +-// └── d3 # 0700 +-// └── f1 # whiteout, 0644 ++// ++// . ++// ├── d1 # opaque, 0700 ++// │ └── f1 # empty file, 0600 ++// ├── d2 # opaque, 0750 ++// │ └── f1 # empty file, 0660 ++// └── d3 # 0700 ++// └── f1 # whiteout, 0644 + func setupOverlayTestDir(t *testing.T, src string) { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") + skip.If(t, sys.RunningInUserNS(), "skipping test that requires initial userns (trusted.overlay.opaque xattr cannot be set in userns, even with Ubuntu kernel)") +diff --git a/pkg/archive/copy_unix_test.go b/pkg/archive/copy_unix_test.go +index efb20e225d..2f421fe78e 100644 +--- a/pkg/archive/copy_unix_test.go ++++ b/pkg/archive/copy_unix_test.go +@@ -297,9 +297,10 @@ func TestCopyLongDstFilename(t *testing.T) { + // J | yes | yes | yes | yes | - | copy dir contents + // + +-// A. SRC specifies a file and DST (no trailing path separator) doesn't +-// exist. This should create a file with the name DST and copy the +-// contents of the source file into it. ++// A. SRC specifies a file and DST (no trailing path separator) doesn't exist. ++// ++// This should create a file with the name DST and copy the contents of the source ++// file into it. + func TestCopyCaseA(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -339,9 +340,10 @@ func TestCopyCaseA(t *testing.T) { + assert.NilError(t, err) + } + +-// B. SRC specifies a file and DST (with trailing path separator) doesn't +-// exist. This should cause an error because the copy operation cannot +-// create a directory when copying a single file. ++// B. SRC specifies a file and DST (with trailing path separator) doesn't exist. ++// ++// This should cause an error because the copy operation cannot create a directory ++// when copying a single file. + func TestCopyCaseB(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -373,8 +375,9 @@ func TestCopyCaseB(t *testing.T) { + + } + +-// C. SRC specifies a file and DST exists as a file. This should overwrite +-// the file at DST with the contents of the source file. ++// C. SRC specifies a file and DST exists as a file. ++// ++// This should overwrite the file at DST with the contents of the source file. + func TestCopyCaseC(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -401,9 +404,9 @@ func TestCopyCaseC(t *testing.T) { + assert.NilError(t, err) + } + +-// C. Symbol link following version: +-// SRC specifies a file and DST exists as a file. This should overwrite +-// the file at DST with the contents of the source file. ++// C. Symbol link following version: SRC specifies a file and DST exists as a file. ++// ++// This should overwrite the file at DST with the contents of the source file. + func TestCopyCaseCFSym(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -438,9 +441,10 @@ func TestCopyCaseCFSym(t *testing.T) { + assert.NilError(t, err) + } + +-// D. SRC specifies a file and DST exists as a directory. This should place +-// a copy of the source file inside it using the basename from SRC. Ensure +-// this works whether DST has a trailing path separator or not. ++// D. SRC specifies a file and DST exists as a directory. ++// ++// This should place a copy of the source file inside it using the basename from ++// SRC. Ensure this works whether DST has a trailing path separator or not. + func TestCopyCaseD(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -487,10 +491,10 @@ func TestCopyCaseD(t *testing.T) { + assert.NilError(t, err) + } + +-// D. Symbol link following version: +-// SRC specifies a file and DST exists as a directory. This should place +-// a copy of the source file inside it using the basename from SRC. Ensure +-// this works whether DST has a trailing path separator or not. ++// D. Symbol link following version: SRC specifies a file and DST exists as a directory. ++// ++// This should place a copy of the source file inside it using the basename from ++// SRC. Ensure this works whether DST has a trailing path separator or not. + func TestCopyCaseDFSym(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -538,10 +542,11 @@ func TestCopyCaseDFSym(t *testing.T) { + assert.NilError(t, err) + } + +-// E. SRC specifies a directory and DST does not exist. This should create a +-// directory at DST and copy the contents of the SRC directory into the DST +-// directory. Ensure this works whether DST has a trailing path separator or +-// not. ++// E. SRC specifies a directory and DST does not exist. ++// ++// This should create a directory at DST and copy the contents of the SRC directory ++// into the DST directory. Ensure this works whether DST has a trailing path ++// separator or not. + func TestCopyCaseE(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -581,11 +586,11 @@ func TestCopyCaseE(t *testing.T) { + assert.NilError(t, err) + } + +-// E. Symbol link following version: +-// SRC specifies a directory and DST does not exist. This should create a +-// directory at DST and copy the contents of the SRC directory into the DST +-// directory. Ensure this works whether DST has a trailing path separator or +-// not. ++// E. Symbol link following version: SRC specifies a directory and DST does not exist. ++// ++// This should create a directory at DST and copy the contents of the SRC directory ++// into the DST directory. Ensure this works whether DST has a trailing path ++// separator or not. + func TestCopyCaseEFSym(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -626,8 +631,10 @@ func TestCopyCaseEFSym(t *testing.T) { + assert.NilError(t, err) + } + +-// F. SRC specifies a directory and DST exists as a file. This should cause an +-// error as it is not possible to overwrite a file with a directory. ++// F. SRC specifies a directory and DST exists as a file. ++// ++// This should cause an error as it is not possible to overwrite a file with a ++// directory. + func TestCopyCaseF(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -660,9 +667,10 @@ func TestCopyCaseF(t *testing.T) { + } + } + +-// G. SRC specifies a directory and DST exists as a directory. This should copy +-// the SRC directory and all its contents to the DST directory. Ensure this +-// works whether DST has a trailing path separator or not. ++// G. SRC specifies a directory and DST exists as a directory. ++// ++// This should copy the SRC directory and all its contents to the DST directory. ++// Ensure this works whether DST has a trailing path separator or not. + func TestCopyCaseG(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -704,10 +712,10 @@ func TestCopyCaseG(t *testing.T) { + assert.NilError(t, err) + } + +-// G. Symbol link version: +-// SRC specifies a directory and DST exists as a directory. This should copy +-// the SRC directory and all its contents to the DST directory. Ensure this +-// works whether DST has a trailing path separator or not. ++// G. Symbol link version: SRC specifies a directory and DST exists as a directory. ++// ++// This should copy the SRC directory and all its contents to the DST directory. ++// Ensure this works whether DST has a trailing path separator or not. + func TestCopyCaseGFSym(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -750,10 +758,11 @@ func TestCopyCaseGFSym(t *testing.T) { + assert.NilError(t, err) + } + +-// H. SRC specifies a directory's contents only and DST does not exist. This +-// should create a directory at DST and copy the contents of the SRC +-// directory (but not the directory itself) into the DST directory. Ensure +-// this works whether DST has a trailing path separator or not. ++// H. SRC specifies a directory's contents only and DST does not exist. ++// ++// This should create a directory at DST and copy the contents of the SRC ++// directory (but not the directory itself) into the DST directory. Ensure ++// this works whether DST has a trailing path separator or not. + func TestCopyCaseH(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -797,11 +806,11 @@ func TestCopyCaseH(t *testing.T) { + } + } + +-// H. Symbol link following version: +-// SRC specifies a directory's contents only and DST does not exist. This +-// should create a directory at DST and copy the contents of the SRC +-// directory (but not the directory itself) into the DST directory. Ensure +-// this works whether DST has a trailing path separator or not. ++// H. Symbol link following version: SRC specifies a directory's contents only and DST does not exist. ++// ++// This should create a directory at DST and copy the contents of the SRC ++// directory (but not the directory itself) into the DST directory. Ensure ++// this works whether DST has a trailing path separator or not. + func TestCopyCaseHFSym(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -846,9 +855,10 @@ func TestCopyCaseHFSym(t *testing.T) { + } + } + +-// I. SRC specifies a directory's contents only and DST exists as a file. This +-// should cause an error as it is not possible to overwrite a file with a +-// directory. ++// I. SRC specifies a directory's contents only and DST exists as a file. ++// ++// This should cause an error as it is not possible to overwrite a file with a ++// directory. + func TestCopyCaseI(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -882,9 +892,10 @@ func TestCopyCaseI(t *testing.T) { + } + + // J. SRC specifies a directory's contents only and DST exists as a directory. +-// This should copy the contents of the SRC directory (but not the directory +-// itself) into the DST directory. Ensure this works whether DST has a +-// trailing path separator or not. ++// ++// This should copy the contents of the SRC directory (but not the directory ++// itself) into the DST directory. Ensure this works whether DST has a ++// trailing path separator or not. + func TestCopyCaseJ(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +@@ -930,11 +941,11 @@ func TestCopyCaseJ(t *testing.T) { + assert.NilError(t, err) + } + +-// J. Symbol link following version: +-// SRC specifies a directory's contents only and DST exists as a directory. +-// This should copy the contents of the SRC directory (but not the directory +-// itself) into the DST directory. Ensure this works whether DST has a +-// trailing path separator or not. ++// J. Symbol link following version: SRC specifies a directory's contents only and DST exists as a directory. ++// ++// This should copy the contents of the SRC directory (but not the directory ++// itself) into the DST directory. Ensure this works whether DST has a ++// trailing path separator or not. + func TestCopyCaseJFSym(t *testing.T) { + tmpDirA, tmpDirB := getTestTempDirs(t) + defer removeAllPaths(tmpDirA, tmpDirB) +diff --git a/pkg/archive/wrap.go b/pkg/archive/wrap.go +index 85435694cf..032db82cea 100644 +--- a/pkg/archive/wrap.go ++++ b/pkg/archive/wrap.go +@@ -17,8 +17,8 @@ import ( + // Generate("foo.txt", "hello world", "emptyfile") + // + // The above call will return an archive with 2 files: +-// * ./foo.txt with content "hello world" +-// * ./empty with empty content ++// - ./foo.txt with content "hello world" ++// - ./empty with empty content + // + // FIXME: stream content instead of buffering + // FIXME: specify permissions and other archive metadata +diff --git a/pkg/chrootarchive/archive.go b/pkg/chrootarchive/archive.go +index 427abee7e8..ebf5db8e6c 100644 +--- a/pkg/chrootarchive/archive.go ++++ b/pkg/chrootarchive/archive.go +@@ -33,7 +33,7 @@ func NewArchiver(idMapping *idtools.IdentityMapping) *archive.Archiver { + // Untar reads a stream of bytes from `archive`, parses it as a tar archive, + // and unpacks it into the directory at `dest`. + // The archive may be compressed with one of the following algorithms: +-// identity (uncompressed), gzip, bzip2, xz. ++// identity (uncompressed), gzip, bzip2, xz. + func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error { + return untarHandler(tarArchive, dest, options, true, dest) + } +diff --git a/pkg/devicemapper/devmapper.go b/pkg/devicemapper/devmapper.go +index 05456c67ee..688b7f9932 100644 +--- a/pkg/devicemapper/devmapper.go ++++ b/pkg/devicemapper/devmapper.go +@@ -15,7 +15,7 @@ import ( + ) + + // Same as DM_DEVICE_* enum values from libdevmapper.h +-//nolint: deadcode,unused,varcheck ++// nolint: deadcode,unused,varcheck + const ( + deviceCreate TaskType = iota + deviceReload +diff --git a/pkg/devicemapper/devmapper_log.go b/pkg/devicemapper/devmapper_log.go +index aa47368258..ed7343a278 100644 +--- a/pkg/devicemapper/devmapper_log.go ++++ b/pkg/devicemapper/devmapper_log.go +@@ -39,6 +39,7 @@ func LogInit(logger DevmapperLogger) { + // because we are using callbacks, this function will be called for *every* log + // in libdm (even debug ones because there's no way of setting the verbosity + // level for an external logging callback). ++// + //export DevmapperLogCallback + func DevmapperLogCallback(level C.int, file *C.char, line, dmErrnoOrClass C.int, message *C.char) { + msg := C.GoString(message) +diff --git a/pkg/mount/deprecated.go b/pkg/mount/deprecated.go +index 16c8e5952d..6112d36da9 100644 +--- a/pkg/mount/deprecated.go ++++ b/pkg/mount/deprecated.go +@@ -22,6 +22,7 @@ type ( + ) + + // Deprecated: use github.com/moby/sys/mountinfo instead. ++// + //nolint:golint + var ( + Mounted = mountinfo.Mounted +@@ -34,6 +35,7 @@ var ( + // GetMounts is a function. + // + // Deprecated: use github.com/moby/sys/mountinfo.GetMounts() instead. ++// + //nolint:golint + func GetMounts(f FilterFunc) ([]*Info, error) { + fi := func(i *mountinfo.Info) (skip, stop bool) { +diff --git a/pkg/mount/deprecated_linux.go b/pkg/mount/deprecated_linux.go +index e4a4407a32..13acd5f87e 100644 +--- a/pkg/mount/deprecated_linux.go ++++ b/pkg/mount/deprecated_linux.go +@@ -5,6 +5,7 @@ import ( + ) + + // Deprecated: use github.com/moby/sys/mount instead. ++// + //nolint:golint + var ( + MakeMount = sysmount.MakeMount +diff --git a/pkg/mount/deprecated_unix.go b/pkg/mount/deprecated_unix.go +index 6c79c20bf0..202a85fa76 100644 +--- a/pkg/mount/deprecated_unix.go ++++ b/pkg/mount/deprecated_unix.go +@@ -11,6 +11,7 @@ import ( + ) + + // Deprecated: use github.com/moby/sys/mount instead. ++// + //nolint:golint + var ( + Mount = sysmount.Mount +@@ -20,6 +21,7 @@ var ( + ) + + // Deprecated: use github.com/moby/sys/mount instead. ++// + //nolint:golint + const ( + RDONLY = sysmount.RDONLY +@@ -47,6 +49,7 @@ const ( + ) + + // Deprecated: use github.com/moby/sys/mount instead. ++// + //nolint:golint + var ( + MergeTmpfsOptions = sysmount.MergeTmpfsOptions +diff --git a/pkg/parsers/parsers.go b/pkg/parsers/parsers.go +index 068e524807..e6d7b33ec0 100644 +--- a/pkg/parsers/parsers.go ++++ b/pkg/parsers/parsers.go +@@ -25,13 +25,14 @@ func ParseKeyValueOpt(opt string) (string, string, error) { + // set to `true`. Values larger than `maximum` cause an error if max is non zero, + // in order to stop the map becoming excessively large. + // Supported formats: +-// 7 +-// 1-6 +-// 0,3-4,7,8-10 +-// 0-0,0,1-7 +-// 03,1-3 <- this is gonna get parsed as [1,2,3] +-// 3,2,1 +-// 0-2,3,1 ++// ++// 7 ++// 1-6 ++// 0,3-4,7,8-10 ++// 0-0,0,1-7 ++// 03,1-3 <- this is gonna get parsed as [1,2,3] ++// 3,2,1 ++// 0-2,3,1 + func ParseUintListMaximum(val string, maximum int) (map[int]bool, error) { + return parseUintList(val, maximum) + } +@@ -42,13 +43,14 @@ func ParseUintListMaximum(val string, maximum int) (map[int]bool, error) { + // input string. It returns a `map[int]bool` with available elements from `val` + // set to `true`. + // Supported formats: +-// 7 +-// 1-6 +-// 0,3-4,7,8-10 +-// 0-0,0,1-7 +-// 03,1-3 <- this is gonna get parsed as [1,2,3] +-// 3,2,1 +-// 0-2,3,1 ++// ++// 7 ++// 1-6 ++// 0,3-4,7,8-10 ++// 0-0,0,1-7 ++// 03,1-3 <- this is gonna get parsed as [1,2,3] ++// 3,2,1 ++// 0-2,3,1 + func ParseUintList(val string) (map[int]bool, error) { + return parseUintList(val, 0) + } +diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go +index 2371e92101..94ab71e922 100644 +--- a/pkg/plugins/plugins.go ++++ b/pkg/plugins/plugins.go +@@ -13,7 +13,7 @@ + // A handshake is send at /Plugin.Activate, and plugins are expected to return + // a Manifest with a list of Docker subsystems which this plugin implements. + // +-// In order to use a plugins, you can use the ``Get`` with the name of the ++// In order to use a plugins, you can use the `Get` with the name of the + // plugin and the subsystem it implements. + // + // plugin, err := plugins.Get("example", "VolumeDriver") +diff --git a/pkg/signal/trap.go b/pkg/signal/trap.go +index a277b95629..9ebdadeb3e 100644 +--- a/pkg/signal/trap.go ++++ b/pkg/signal/trap.go +@@ -18,14 +18,13 @@ import ( + // behavior expected from a vanilla unix command-line tool in general + // (and the Docker engine in particular). + // +-// * If SIGINT or SIGTERM are received, `cleanup` is called, then the process is terminated. +-// * If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is +-// skipped and the process is terminated immediately (allows force quit of stuck daemon) +-// * A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit. +-// * Ignore SIGPIPE events. These are generated by systemd when journald is restarted while +-// the docker daemon is not restarted and also running under systemd. +-// Fixes https://github.com/docker/docker/issues/19728 +-// ++// - If SIGINT or SIGTERM are received, `cleanup` is called, then the process is terminated. ++// - If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is ++// skipped and the process is terminated immediately (allows force quit of stuck daemon) ++// - A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit. ++// - Ignore SIGPIPE events. These are generated by systemd when journald is restarted while ++// the docker daemon is not restarted and also running under systemd. ++// Fixes https://github.com/docker/docker/issues/19728 + func Trap(cleanup func(), logger interface { + Info(args ...interface{}) + }) { +diff --git a/pkg/system/meminfo_windows.go b/pkg/system/meminfo_windows.go +index 6ed93f2fe2..124d2c502d 100644 +--- a/pkg/system/meminfo_windows.go ++++ b/pkg/system/meminfo_windows.go +@@ -27,7 +27,7 @@ type memorystatusex struct { + } + + // ReadMemInfo retrieves memory statistics of the host system and returns a +-// MemInfo type. ++// MemInfo type. + func ReadMemInfo() (*MemInfo, error) { + msi := &memorystatusex{ + dwLength: 64, +diff --git a/plugin/store.go b/plugin/store.go +index 114fcf17a1..76d9acbfd6 100644 +--- a/plugin/store.go ++++ b/plugin/store.go +@@ -14,16 +14,14 @@ import ( + "github.com/sirupsen/logrus" + ) + +-/* allowV1PluginsFallback determines daemon's support for V1 plugins. +- * When the time comes to remove support for V1 plugins, flipping +- * this bool is all that will be needed. +- */ ++// allowV1PluginsFallback determines daemon's support for V1 plugins. ++// When the time comes to remove support for V1 plugins, flipping ++// this bool is all that will be needed. + const allowV1PluginsFallback = true + +-/* defaultAPIVersion is the version of the plugin API for volume, network, +- IPAM and authz. This is a very stable API. When we update this API, then +- pluginType should include a version. e.g. "networkdriver/2.0". +-*/ ++// defaultAPIVersion is the version of the plugin API for volume, network, ++// IPAM and authz. This is a very stable API. When we update this API, then ++// pluginType should include a version. e.g. "networkdriver/2.0". + const defaultAPIVersion = "1.0" + + // GetV2Plugin retrieves a plugin by name, id or partial ID. +diff --git a/quota/projectquota.go b/quota/projectquota.go +index 1230fdb22c..af24cd9391 100644 +--- a/quota/projectquota.go ++++ b/quota/projectquota.go +@@ -102,9 +102,10 @@ func (state *pquotaState) updateMinProjID(minProjectID uint32) { + // This test will fail if the backing fs is not xfs. + // + // xfs_quota tool can be used to assign a project id to the driver home directory, e.g.: +-// echo 999:/var/lib/docker/overlay2 >> /etc/projects +-// echo docker:999 >> /etc/projid +-// xfs_quota -x -c 'project -s docker' / ++// ++// echo 999:/var/lib/docker/overlay2 >> /etc/projects ++// echo docker:999 >> /etc/projid ++// xfs_quota -x -c 'project -s docker' / + // + // In that case, the home directory project id will be used as a "start offset" + // and all containers will be assigned larger project ids (e.g. >= 1000). +@@ -113,7 +114,6 @@ func (state *pquotaState) updateMinProjID(minProjectID uint32) { + // Then try to create a test directory with the next project id and set a quota + // on it. If that works, continue to scan existing containers to map allocated + // project ids. +-// + func NewControl(basePath string) (*Control, error) { + // + // If we are running in a user namespace quota won't be supported for +diff --git a/volume/drivers/extpoint.go b/volume/drivers/extpoint.go +index 3878736cbb..970c909f72 100644 +--- a/volume/drivers/extpoint.go ++++ b/volume/drivers/extpoint.go +@@ -21,13 +21,13 @@ const extName = "VolumeDriver" + // volumeDriver defines the available functions that volume plugins must implement. + // This interface is only defined to generate the proxy objects. + // It's not intended to be public or reused. +-//nolint: deadcode ++// nolint: deadcode,unused,varcheck + type volumeDriver interface { + // Create a volume with the given name + Create(name string, opts map[string]string) (err error) + // Remove the volume with the given name + Remove(name string) (err error) +- // Get the mountpoint of the given volume ++ // Path returns the mountpoint of the given volume. + Path(name string) (mountpoint string, err error) + // Mount the given volume and return the mountpoint + Mount(name, id string) (mountpoint string, err error) +diff --git a/volume/service/store.go b/volume/service/store.go +index 7989f8ddf5..b06890c2d2 100644 +--- a/volume/service/store.go ++++ b/volume/service/store.go +@@ -549,7 +549,7 @@ func volumeExists(ctx context.Context, store *drivers.Store, v volume.Volume) (b + // create asks the given driver to create a volume with the name/opts. + // If a volume with the name is already known, it will ask the stored driver for the volume. + // If the passed in driver name does not match the driver name which is stored +-// for the given volume name, an error is returned after checking if the reference is stale. ++// for the given volume name, an error is returned after checking if the reference is stale. + // If the reference is stale, it will be purged and this create can continue. + // It is expected that callers of this function hold any necessary locks. + func (s *VolumeStore) create(ctx context.Context, name, driverName string, opts, labels map[string]string) (volume.Volume, error) { +@@ -728,9 +728,9 @@ func (s *VolumeStore) getVolume(ctx context.Context, name, driverName string) (v + + // lookupVolume gets the specified volume from the specified driver. + // This will only return errors related to communications with the driver. +-// If the driver returns an error that is not communication related the +-// error is logged but not returned. +-// If the volume is not found it will return `nil, nil`` ++// If the driver returns an error that is not communication related, the error ++// is logged but not returned. ++// If the volume is not found it will return `nil, nil` + // TODO(@cpuguy83): plumb through the context to lower level components + func lookupVolume(ctx context.Context, store *drivers.Store, driverName, volumeName string) (volume.Volume, error) { + if driverName == "" { +-- +2.21.0 + diff --git a/patch/backport-0012-moby20.10-fix-formatting-of-nolint-tags-for-go1.19.patch b/patch/backport-0012-moby20.10-fix-formatting-of-nolint-tags-for-go1.19.patch new file mode 100644 index 0000000..c962772 --- /dev/null +++ b/patch/backport-0012-moby20.10-fix-formatting-of-nolint-tags-for-go1.19.patch @@ -0,0 +1,64 @@ +From 9a5d1b295e0f2f02f1e74385cd0a348d698377c7 Mon Sep 17 00:00:00 2001 +From: Sebastiaan van Stijn +Date: Wed, 13 Jul 2022 22:30:47 +0200 +Subject: [PATCH 12/16] fix formatting of "nolint" tags for go1.19 + +The correct formatting for machine-readable comments is; + + //:[,