vendor: update c/{common,image,storage}

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2023-11-14 17:55:28 +01:00
parent a9a581a443
commit c174e91624
No known key found for this signature in database
GPG Key ID: 67E38F7A8BA21772
29 changed files with 235 additions and 375 deletions

View File

@ -14,6 +14,7 @@ import (
is "github.com/containers/image/v5/storage"
"github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/unshare"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@ -28,7 +29,7 @@ func getStore(c *cobra.Command) (storage.Store, error) {
if err := setXDGRuntimeDir(); err != nil {
return nil, err
}
options, err := storage.DefaultStoreOptions(unshare.GetRootlessUID() > 0, unshare.GetRootlessUID())
options, err := storage.DefaultStoreOptions()
if err != nil {
return nil, err
}
@ -106,7 +107,7 @@ func getStore(c *cobra.Command) (storage.Store, error) {
// setXDGRuntimeDir sets XDG_RUNTIME_DIR when if it is unset under rootless
func setXDGRuntimeDir() error {
if unshare.IsRootless() && os.Getenv("XDG_RUNTIME_DIR") == "" {
runtimeDir, err := storage.GetRootlessRuntimeDir(unshare.GetRootlessUID())
runtimeDir, err := homedir.GetRuntimeDir()
if err != nil {
return err
}

View File

@ -17,7 +17,7 @@ import (
var (
signaturePolicyPath = ""
storeOptions, _ = storage.DefaultStoreOptions(false, 0)
storeOptions, _ = storage.DefaultStoreOptions()
testSystemContext = types.SystemContext{}
)

View File

@ -67,7 +67,7 @@ func init() {
var (
defaultStoreDriverOptions []string
)
storageOptions, err := storage.DefaultStoreOptions(false, 0)
storageOptions, err := storage.DefaultStoreOptions()
if err != nil {
logrus.Errorf(err.Error())
os.Exit(1)

6
go.mod
View File

@ -6,11 +6,11 @@ require (
github.com/containerd/containerd v1.7.9
github.com/containernetworking/cni v1.1.2
github.com/containernetworking/plugins v1.3.0
github.com/containers/common v0.57.0
github.com/containers/image/v5 v5.29.0
github.com/containers/common v0.57.1-0.20231121115347-e2da7bec2245
github.com/containers/image/v5 v5.29.1-0.20231120202631-293b00ba7166
github.com/containers/luksy v0.0.0-20231030195837-b5a7f79da98b
github.com/containers/ocicrypt v1.1.9
github.com/containers/storage v1.51.0
github.com/containers/storage v1.51.1-0.20231120144510-2cf61989a5bc
github.com/cyphar/filepath-securejoin v0.2.4
github.com/docker/distribution v2.8.3+incompatible
github.com/docker/docker v24.0.7+incompatible

12
go.sum
View File

@ -54,18 +54,18 @@ github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl3
github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
github.com/containernetworking/plugins v1.3.0 h1:QVNXMT6XloyMUoO2wUOqWTC1hWFV62Q6mVDp5H1HnjM=
github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0=
github.com/containers/common v0.57.0 h1:5O/+6QUBafKK0/zeok9y1rLPukfWgdE0sT4nuzmyAqk=
github.com/containers/common v0.57.0/go.mod h1:t/Z+/sFrapvFMEJe3YnecN49/Tae2wYEQShbEN6SRaU=
github.com/containers/image/v5 v5.29.0 h1:9+nhS/ZM7c4Kuzu5tJ0NMpxrgoryOJ2HAYTgG8Ny7j4=
github.com/containers/image/v5 v5.29.0/go.mod h1:kQ7qcDsps424ZAz24thD+x7+dJw1vgur3A9tTDsj97E=
github.com/containers/common v0.57.1-0.20231121115347-e2da7bec2245 h1:JjjvtSd5dwt8CRZX9eZyxNx9IKnE6TT5qYuDqePk2n4=
github.com/containers/common v0.57.1-0.20231121115347-e2da7bec2245/go.mod h1:5C4EkX50fgbJZdZPdX3QSVGbXIe3wuhWz1G7e5JBxbs=
github.com/containers/image/v5 v5.29.1-0.20231120202631-293b00ba7166 h1:Dz4ryT8VDKn6U+oWPtsihAV2eG7uFc+LYS7UjHjLcwk=
github.com/containers/image/v5 v5.29.1-0.20231120202631-293b00ba7166/go.mod h1:0uOgAiVgmF8+VCXltRYmncWjkDYc+jFma49NKNz0cS4=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/luksy v0.0.0-20231030195837-b5a7f79da98b h1:8XvNAm+g7ivwPUkyiHvBs7z356JWpK9a0FDaek86+sY=
github.com/containers/luksy v0.0.0-20231030195837-b5a7f79da98b/go.mod h1:menB9p4o5HckgcLW6cO0+dl6+axkVmSqKlrNcratsh4=
github.com/containers/ocicrypt v1.1.9 h1:2Csfba4jse85Raxk5HIyEk8OwZNjRvfkhEGijOjIdEM=
github.com/containers/ocicrypt v1.1.9/go.mod h1:dTKx1918d8TDkxXvarscpNVY+lyPakPNFN4jwA9GBys=
github.com/containers/storage v1.51.0 h1:AowbcpiWXzAjHosKz7MKvPEqpyX+ryZA/ZurytRrFNA=
github.com/containers/storage v1.51.0/go.mod h1:ybl8a3j1PPtpyaEi/5A6TOFs+5TrEyObeKJzVtkUlfc=
github.com/containers/storage v1.51.1-0.20231120144510-2cf61989a5bc h1:K+fKkKkqwwY3YYM+RejJ6OcbCRZfDRZLoKsMMBAT2Bw=
github.com/containers/storage v1.51.1-0.20231120144510-2cf61989a5bc/go.mod h1:oz9n9uia9xtxDQhw7nnlpMID5YKbHmMZsVFy4rR+5+s=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=

View File

@ -22,7 +22,7 @@ func importBuilderDataFromImage(ctx context.Context, store storage.Store, system
return nil, errors.New("Internal error: imageID is empty in importBuilderDataFromImage")
}
storeopts, err := storage.DefaultStoreOptions(false, 0)
storeopts, err := storage.DefaultStoreOptions()
if err != nil {
return nil, err
}

View File

@ -39,7 +39,7 @@ func main() {
unshare.MaybeReexecUsingUserNamespace(false)
storeOptions, err := storage.DefaultStoreOptionsAutoDetectUID()
storeOptions, err := storage.DefaultStoreOptions()
if err != nil {
storeOptions = storage.StoreOptions{}
}

View File

@ -233,7 +233,7 @@ func (p *BuildAhTest) CreateArtifact(image string) error {
// RestoreArtifact puts the cached image into our test store
func (p *BuildAhTest) RestoreArtifact(image string) error {
storeOptions, _ := sstorage.DefaultStoreOptions(false, 0)
storeOptions, _ := sstorage.DefaultStoreOptions()
storeOptions.GraphDriverName = os.Getenv("STORAGE_DRIVER")
if storeOptions.GraphDriverName == "" {
storeOptions.GraphDriverName = "vfs"

View File

@ -28,7 +28,7 @@ func main() {
}
unshare.MaybeReexecUsingUserNamespace(false)
storeOptions, err := storage.DefaultStoreOptionsAutoDetectUID()
storeOptions, err := storage.DefaultStoreOptions()
if err != nil {
storeOptions = storage.StoreOptions{}
}

View File

@ -21,7 +21,7 @@ func main() {
}
unshare.MaybeReexecUsingUserNamespace(false)
buildStoreOptions, err := storage.DefaultStoreOptions(unshare.IsRootless(), unshare.GetRootlessUID())
buildStoreOptions, err := storage.DefaultStoreOptions()
if err != nil {
panic(err)
}

View File

@ -180,22 +180,26 @@ func (i *Image) Inspect(ctx context.Context, options *InspectOptions) (*ImageDat
}
// Docker image
case manifest.DockerV2Schema1MediaType, manifest.DockerV2Schema2MediaType:
case manifest.DockerV2Schema2MediaType:
rawConfig, err := i.rawConfigBlob(ctx)
if err != nil {
return nil, err
}
var dockerManifest manifest.Schema2V1Image
if err := json.Unmarshal(rawConfig, &dockerManifest); err != nil {
var dockerConfig manifest.Schema2V1Image
if err := json.Unmarshal(rawConfig, &dockerConfig); err != nil {
return nil, err
}
data.Comment = dockerManifest.Comment
data.Comment = dockerConfig.Comment
// NOTE: Health checks may be listed in the container config or
// the config.
data.HealthCheck = dockerManifest.ContainerConfig.Healthcheck
if data.HealthCheck == nil && dockerManifest.Config != nil {
data.HealthCheck = dockerManifest.Config.Healthcheck
data.HealthCheck = dockerConfig.ContainerConfig.Healthcheck
if data.HealthCheck == nil && dockerConfig.Config != nil {
data.HealthCheck = dockerConfig.Config.Healthcheck
}
case manifest.DockerV2Schema1MediaType, manifest.DockerV2Schema1SignedMediaType:
// There seem to be at least _some_ images with .Healthcheck set in schema1 (possibly just as an artifact
// of testing format conversion?), so this could plausibly read these values.
}
if data.Annotations == nil {

View File

@ -13,7 +13,6 @@ import (
nettypes "github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/cgroupv2"
"github.com/containers/common/pkg/util"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/unshare"
"github.com/containers/storage/types"
@ -196,7 +195,9 @@ func defaultConfig() (*Config, error) {
}
defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath
if useUserConfigLocations() {
// NOTE: For now we want Windows to use system locations.
// GetRootlessUID == -1 on Windows, so exclude negative range
if unshare.GetRootlessUID() > 0 {
configHome, err := homedir.GetConfigHome()
if err != nil {
return nil, err
@ -320,7 +321,7 @@ func defaultEngineConfig() (*EngineConfig, error) {
return nil, err
}
}
storeOpts, err := types.DefaultStoreOptions(useUserConfigLocations(), unshare.GetRootlessUID())
storeOpts, err := types.DefaultStoreOptions()
if err != nil {
return nil, err
}
@ -480,11 +481,14 @@ func defaultEngineConfig() (*EngineConfig, error) {
}
func defaultTmpDir() (string, error) {
if !useUserConfigLocations() {
// NOTE: For now we want Windows to use system locations.
// GetRootlessUID == -1 on Windows, so exclude negative range
rootless := unshare.GetRootlessUID() > 0
if !rootless {
return getLibpodTmpDir(), nil
}
runtimeDir, err := util.GetRuntimeDir()
runtimeDir, err := homedir.GetRuntimeDir()
if err != nil {
return "", err
}
@ -669,12 +673,6 @@ func getDefaultSSHConfig() string {
return filepath.Join(dirname, ".ssh", "config")
}
func useUserConfigLocations() bool {
// NOTE: For now we want Windows to use system locations.
// GetRootlessUID == -1 on Windows, so exclude negative range
return unshare.GetRootlessUID() > 0
}
// getDefaultImage returns the default machine image stream
// On Windows this refers to the Fedora major release number
func getDefaultMachineImage() string {

View File

@ -14,7 +14,7 @@ import (
// ValidateVolumeOpts validates a volume's options
func ValidateVolumeOpts(options []string) ([]string, error) {
var foundRootPropagation, foundRWRO, foundLabelChange, bindType, foundExec, foundDev, foundSuid, foundChown, foundUpperDir, foundWorkDir, foundCopy int
var foundRootPropagation, foundRWRO, foundLabelChange, bindType, foundExec, foundDev, foundSuid, foundChown, foundUpperDir, foundWorkDir, foundCopy, foundCopySymlink int
finalOpts := make([]string, 0, len(options))
for _, opt := range options {
// support advanced options like upperdir=/path, workdir=/path
@ -93,6 +93,11 @@ func ValidateVolumeOpts(options []string) ([]string, error) {
if foundCopy > 1 {
return nil, fmt.Errorf("invalid options %q, can only specify 1 'copy' or 'nocopy' option", strings.Join(options, ", "))
}
case "no-dereference":
foundCopySymlink++
if foundCopySymlink > 1 {
return nil, fmt.Errorf("invalid options %q, can only specify 1 'no-dereference' option", strings.Join(options, ", "))
}
default:
return nil, fmt.Errorf("invalid option type %q", opt)
}

View File

@ -1,91 +0,0 @@
//go:build linux || darwin || freebsd
// +build linux darwin freebsd
package util
import (
"errors"
"fmt"
"os"
"path/filepath"
"sync"
"syscall"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
)
var (
rootlessRuntimeDirOnce sync.Once
rootlessRuntimeDir string
)
// isWriteableOnlyByOwner checks that the specified permission mask allows write
// access only to the owner.
func isWriteableOnlyByOwner(perm os.FileMode) bool {
return (perm & 0o722) == 0o700
}
// GetRuntimeDir returns the runtime directory
func GetRuntimeDir() (string, error) {
var rootlessRuntimeDirError error
rootlessRuntimeDirOnce.Do(func() {
runtimeDir, err := homedir.GetRuntimeDir()
if err != nil {
logrus.Debug(err)
}
if runtimeDir != "" {
st, err := os.Stat(runtimeDir)
if err != nil {
rootlessRuntimeDirError = err
return
}
if int(st.Sys().(*syscall.Stat_t).Uid) != os.Geteuid() {
rootlessRuntimeDirError = fmt.Errorf("XDG_RUNTIME_DIR directory %q is not owned by the current user", runtimeDir)
return
}
}
uid := fmt.Sprintf("%d", unshare.GetRootlessUID())
if runtimeDir == "" {
tmpDir := filepath.Join("/run", "user", uid)
if err := os.MkdirAll(tmpDir, 0o700); err != nil {
logrus.Debugf("unable to make temp dir: %v", err)
}
st, err := os.Stat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && isWriteableOnlyByOwner(st.Mode().Perm()) {
runtimeDir = tmpDir
}
}
if runtimeDir == "" {
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("podman-run-%s", uid))
if err := os.MkdirAll(tmpDir, 0o700); err != nil {
logrus.Debugf("unable to make temp dir %v", err)
}
st, err := os.Stat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && isWriteableOnlyByOwner(st.Mode().Perm()) {
runtimeDir = tmpDir
}
}
if runtimeDir == "" {
home := os.Getenv("HOME")
if home == "" {
rootlessRuntimeDirError = errors.New("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
return
}
resolvedHome, err := filepath.EvalSymlinks(home)
if err != nil {
rootlessRuntimeDirError = fmt.Errorf("cannot resolve home: %w", err)
return
}
runtimeDir = filepath.Join(resolvedHome, "rundir")
}
rootlessRuntimeDir = runtimeDir
})
if rootlessRuntimeDirError != nil {
return "", rootlessRuntimeDirError
}
return rootlessRuntimeDir, nil
}

View File

@ -1,13 +0,0 @@
//go:build windows
// +build windows
package util
import (
"errors"
)
// getRuntimeDir returns the runtime directory
func GetRuntimeDir() (string, error) {
return "", errors.New("this function is not implemented for windows")
}

View File

@ -1,4 +1,4 @@
package version
// Version is the version of the build.
const Version = "0.57.0"
const Version = "0.57.1-dev"

View File

@ -213,7 +213,7 @@ func (s *storageTransport) GetStore() (storage.Store, error) {
// Return the transport's previously-set store. If we don't have one
// of those, initialize one now.
if s.store == nil {
options, err := storage.DefaultStoreOptionsAutoDetectUID()
options, err := storage.DefaultStoreOptions()
if err != nil {
return nil, err
}

View File

@ -8,10 +8,10 @@ const (
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 29
// VersionPatch is for backwards-compatible bug fixes
VersionPatch = 0
VersionPatch = 1
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""
VersionDev = "-dev"
)
// Version is the specification version that the package types support.

View File

@ -23,7 +23,7 @@ env:
# GCE project where images live
IMAGE_PROJECT: "libpod-218412"
# VM Image built in containers/automation_images
IMAGE_SUFFIX: "c20231004t194547z-f39f38d13"
IMAGE_SUFFIX: "c20231116t174419z-f39f38d13"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}"

View File

@ -1 +1 @@
1.51.0
1.51.1-dev

View File

@ -254,7 +254,7 @@ func convertTarToZstdChunked(destDirectory string, blobSize int64, iss ImageSour
// GetDiffer returns a differ than can be used with ApplyDiffWithDiffer.
func GetDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) {
storeOpts, err := types.DefaultStoreOptionsAutoDetectUID()
storeOpts, err := types.DefaultStoreOptions()
if err != nil {
return nil, err
}

View File

@ -6,21 +6,6 @@ import (
"path/filepath"
)
// GetConfigHome returns XDG_CONFIG_HOME.
// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetConfigHome() (string, error) {
if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" {
return xdgConfigHome, nil
}
home := Get()
if home == "" {
return "", errors.New("could not get either XDG_CONFIG_HOME or HOME")
}
return filepath.Join(home, ".config"), nil
}
// GetDataHome returns XDG_DATA_HOME.
// GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set.
//

View File

@ -8,6 +8,8 @@ package homedir
import (
"errors"
"os"
"path/filepath"
)
// GetRuntimeDir is unsupported on non-linux system.
@ -19,3 +21,18 @@ func GetRuntimeDir() (string, error) {
func StickRuntimeDirContents(files []string) ([]string, error) {
return nil, errors.New("homedir.StickRuntimeDirContents() is not supported on this system")
}
// GetConfigHome returns XDG_CONFIG_HOME.
// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetConfigHome() (string, error) {
if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" {
return xdgConfigHome, nil
}
home := Get()
if home == "" {
return "", errors.New("could not get either XDG_CONFIG_HOME or HOME")
}
return filepath.Join(home, ".config"), nil
}

View File

@ -7,12 +7,16 @@ package homedir
// NOTE: this package has originally been copied from github.com/docker/docker.
import (
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"syscall"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
)
// Key returns the env var name for the user's home dir based on
@ -40,18 +44,6 @@ func GetShortcutString() string {
return "~"
}
// GetRuntimeDir returns XDG_RUNTIME_DIR.
// XDG_RUNTIME_DIR is typically configured via pam_systemd.
// GetRuntimeDir returns non-nil error if XDG_RUNTIME_DIR is not set.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetRuntimeDir() (string, error) {
if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" {
return filepath.EvalSymlinks(xdgRuntimeDir)
}
return "", errors.New("could not get XDG_RUNTIME_DIR")
}
// StickRuntimeDirContents sets the sticky bit on files that are under
// XDG_RUNTIME_DIR, so that the files won't be periodically removed by the system.
//
@ -94,3 +86,95 @@ func stick(f string) error {
m |= os.ModeSticky
return os.Chmod(f, m)
}
var (
rootlessConfigHomeDirError error
rootlessConfigHomeDirOnce sync.Once
rootlessConfigHomeDir string
rootlessRuntimeDirOnce sync.Once
rootlessRuntimeDir string
)
// isWriteableOnlyByOwner checks that the specified permission mask allows write
// access only to the owner.
func isWriteableOnlyByOwner(perm os.FileMode) bool {
return (perm & 0o722) == 0o700
}
// GetConfigHome returns XDG_CONFIG_HOME.
// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetConfigHome() (string, error) {
rootlessConfigHomeDirOnce.Do(func() {
cfgHomeDir := os.Getenv("XDG_CONFIG_HOME")
if cfgHomeDir == "" {
home := Get()
resolvedHome, err := filepath.EvalSymlinks(home)
if err != nil {
rootlessConfigHomeDirError = fmt.Errorf("cannot resolve %s: %w", home, err)
return
}
tmpDir := filepath.Join(resolvedHome, ".config")
_ = os.MkdirAll(tmpDir, 0o700)
st, err := os.Stat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && isWriteableOnlyByOwner(st.Mode().Perm()) {
cfgHomeDir = tmpDir
} else {
rootlessConfigHomeDirError = fmt.Errorf("path %q exists and it is not writeable only by the current user", tmpDir)
return
}
}
rootlessConfigHomeDir = cfgHomeDir
})
return rootlessConfigHomeDir, rootlessConfigHomeDirError
}
// GetRuntimeDir returns a directory suitable to store runtime files.
// The function will try to use the XDG_RUNTIME_DIR env variable if it is set.
// XDG_RUNTIME_DIR is typically configured via pam_systemd.
// If XDG_RUNTIME_DIR is not set, GetRuntimeDir will try to find a suitable
// directory for the current user.
//
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetRuntimeDir() (string, error) {
var rootlessRuntimeDirError error
rootlessRuntimeDirOnce.Do(func() {
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
if runtimeDir != "" {
rootlessRuntimeDir, rootlessRuntimeDirError = filepath.EvalSymlinks(runtimeDir)
return
}
uid := strconv.Itoa(unshare.GetRootlessUID())
if runtimeDir == "" {
tmpDir := filepath.Join("/run", "user", uid)
if err := os.MkdirAll(tmpDir, 0o700); err != nil {
logrus.Debug(err)
}
st, err := os.Lstat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && isWriteableOnlyByOwner(st.Mode().Perm()) {
runtimeDir = tmpDir
}
}
if runtimeDir == "" {
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("storage-run-%s", uid))
if err := os.MkdirAll(tmpDir, 0o700); err != nil {
logrus.Debug(err)
}
st, err := os.Lstat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && isWriteableOnlyByOwner(st.Mode().Perm()) {
runtimeDir = tmpDir
} else {
rootlessRuntimeDirError = fmt.Errorf("path %q exists and it is not writeable only by the current user", tmpDir)
return
}
}
rootlessRuntimeDir = runtimeDir
})
return rootlessRuntimeDir, rootlessRuntimeDirError
}

View File

@ -1,6 +1,7 @@
package storage
import (
_ "embed"
"encoding/base64"
"errors"
"fmt"
@ -2741,7 +2742,13 @@ func (s *store) Status() ([][2]string, error) {
return rlstore.Status()
}
//go:embed VERSION
var storageVersion string
func (s *store) Version() ([][2]string, error) {
if trimmedVersion := strings.TrimSpace(storageVersion); trimmedVersion != "" {
return [][2]string{{"Version", trimmedVersion}}, nil
}
return [][2]string{}, nil
}
@ -3545,8 +3552,8 @@ func SetDefaultConfigFilePath(path string) {
}
// DefaultConfigFile returns the path to the storage config file used
func DefaultConfigFile(rootless bool) (string, error) {
return types.DefaultConfigFile(rootless)
func DefaultConfigFile() (string, error) {
return types.DefaultConfigFile()
}
// ReloadConfigurationFile parses the specified configuration file and overrides

View File

@ -11,7 +11,9 @@ import (
"github.com/BurntSushi/toml"
cfg "github.com/containers/storage/pkg/config"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
)
@ -87,7 +89,7 @@ func loadDefaultStoreOptions() {
_, err := os.Stat(defaultOverrideConfigFile)
if err == nil {
// The DefaultConfigFile(rootless) function returns the path
// The DefaultConfigFile() function returns the path
// of the used storage.conf file, by returning defaultConfigFile
// If override exists containers/storage uses it by default.
defaultConfigFile = defaultOverrideConfigFile
@ -109,21 +111,41 @@ func loadDefaultStoreOptions() {
setDefaults()
}
// defaultStoreOptionsIsolated is an internal implementation detail of DefaultStoreOptions to allow testing.
// Everyone but the tests this is intended for should only call DefaultStoreOptions, never this function.
func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf string) (StoreOptions, error) {
// loadStoreOptions returns the default storage ops for containers
func loadStoreOptions() (StoreOptions, error) {
storageConf, err := DefaultConfigFile()
if err != nil {
return defaultStoreOptions, err
}
return loadStoreOptionsFromConfFile(storageConf)
}
// usePerUserStorage returns whether the user private storage must be used.
// We cannot simply use the unshare.IsRootless() condition, because
// that checks only if the current process needs a user namespace to
// work and it would break cases where the process is already created
// in a user namespace (e.g. nested Podman/Buildah) and the desired
// behavior is to use system paths instead of user private paths.
func usePerUserStorage() bool {
return unshare.IsRootless() && unshare.GetRootlessUID() != 0
}
// loadStoreOptionsFromConfFile is an internal implementation detail of DefaultStoreOptions to allow testing.
// Everyone but the tests this is intended for should only call loadStoreOptions, never this function.
func loadStoreOptionsFromConfFile(storageConf string) (StoreOptions, error) {
var (
defaultRootlessRunRoot string
defaultRootlessGraphRoot string
err error
)
defaultStoreOptionsOnce.Do(loadDefaultStoreOptions)
if loadDefaultStoreOptionsErr != nil {
return StoreOptions{}, loadDefaultStoreOptionsErr
}
storageOpts := defaultStoreOptions
if rootless && rootlessUID != 0 {
storageOpts, err = getRootlessStorageOpts(rootlessUID, storageOpts)
if usePerUserStorage() {
storageOpts, err = getRootlessStorageOpts(storageOpts)
if err != nil {
return storageOpts, err
}
@ -137,7 +159,7 @@ func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf str
defaultRootlessGraphRoot = storageOpts.GraphRoot
storageOpts = StoreOptions{}
reloadConfigurationFileIfNeeded(storageConf, &storageOpts)
if rootless && rootlessUID != 0 {
if usePerUserStorage() {
// If the file did not specify a graphroot or runroot,
// set sane defaults so we don't try and use root-owned
// directories
@ -156,6 +178,7 @@ func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf str
if storageOpts.RunRoot == "" {
return storageOpts, fmt.Errorf("runroot must be set")
}
rootlessUID := unshare.GetRootlessUID()
runRoot, err := expandEnvPath(storageOpts.RunRoot, rootlessUID)
if err != nil {
return storageOpts, err
@ -186,26 +209,17 @@ func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf str
return storageOpts, nil
}
// loadStoreOptions returns the default storage ops for containers
func loadStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) {
storageConf, err := DefaultConfigFile(rootless && rootlessUID != 0)
if err != nil {
return defaultStoreOptions, err
}
return defaultStoreOptionsIsolated(rootless, rootlessUID, storageConf)
}
// UpdateOptions should be called iff container engine received a SIGHUP,
// otherwise use DefaultStoreOptions
func UpdateStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) {
storeOptions, storeError = loadStoreOptions(rootless, rootlessUID)
func UpdateStoreOptions() (StoreOptions, error) {
storeOptions, storeError = loadStoreOptions()
return storeOptions, storeError
}
// DefaultStoreOptions returns the default storage ops for containers
func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) {
func DefaultStoreOptions() (StoreOptions, error) {
once.Do(func() {
storeOptions, storeError = loadStoreOptions(rootless, rootlessUID)
storeOptions, storeError = loadStoreOptions()
})
return storeOptions, storeError
}
@ -270,14 +284,26 @@ func isRootlessDriver(driver string) bool {
}
// getRootlessStorageOpts returns the storage opts for containers running as non root
func getRootlessStorageOpts(rootlessUID int, systemOpts StoreOptions) (StoreOptions, error) {
func getRootlessStorageOpts(systemOpts StoreOptions) (StoreOptions, error) {
var opts StoreOptions
dataDir, rootlessRuntime, err := getRootlessDirInfo(rootlessUID)
rootlessUID := unshare.GetRootlessUID()
dataDir, err := homedir.GetDataHome()
if err != nil {
return opts, err
}
opts.RunRoot = rootlessRuntime
rootlessRuntime, err := homedir.GetRuntimeDir()
if err != nil {
return opts, err
}
opts.RunRoot = filepath.Join(rootlessRuntime, "containers")
if err := os.MkdirAll(opts.RunRoot, 0o700); err != nil {
return opts, fmt.Errorf("unable to make rootless runtime: %w", err)
}
opts.PullOptions = systemOpts.PullOptions
if systemOpts.RootlessStoragePath != "" {
opts.GraphRoot, err = expandEnvPath(systemOpts.RootlessStoragePath, rootlessUID)
@ -343,12 +369,6 @@ func getRootlessStorageOpts(rootlessUID int, systemOpts StoreOptions) (StoreOpti
return opts, nil
}
// DefaultStoreOptionsAutoDetectUID returns the default storage ops for containers
func DefaultStoreOptionsAutoDetectUID() (StoreOptions, error) {
uid := getRootlessUID()
return DefaultStoreOptions(uid != 0, uid)
}
var prevReloadConfig = struct {
storeOptions *StoreOptions
mod time.Time
@ -518,8 +538,8 @@ func Options() (StoreOptions, error) {
}
// Save overwrites the tomlConfig in storage.conf with the given conf
func Save(conf TomlConfig, rootless bool) error {
configFile, err := DefaultConfigFile(rootless)
func Save(conf TomlConfig) error {
configFile, err := DefaultConfigFile()
if err != nil {
return err
}
@ -537,10 +557,10 @@ func Save(conf TomlConfig, rootless bool) error {
}
// StorageConfig is used to retrieve the storage.conf toml in order to overwrite it
func StorageConfig(rootless bool) (*TomlConfig, error) {
func StorageConfig() (*TomlConfig, error) {
config := new(TomlConfig)
configFile, err := DefaultConfigFile(rootless)
configFile, err := DefaultConfigFile()
if err != nil {
return nil, err
}

View File

@ -2,162 +2,15 @@ package types
import (
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/system"
"github.com/sirupsen/logrus"
)
// GetRootlessRuntimeDir returns the runtime directory when running as non root
func GetRootlessRuntimeDir(rootlessUID int) (string, error) {
path, err := getRootlessRuntimeDir(rootlessUID)
if err != nil {
return "", err
}
path = filepath.Join(path, "containers")
if err := os.MkdirAll(path, 0o700); err != nil {
return "", fmt.Errorf("unable to make rootless runtime: %w", err)
}
return path, nil
}
type rootlessRuntimeDirEnvironment interface {
getProcCommandFile() string
getRunUserDir() string
getTmpPerUserDir() string
homeDirGetRuntimeDir() (string, error)
systemLstat(string) (*system.StatT, error)
homedirGet() string
}
type rootlessRuntimeDirEnvironmentImplementation struct {
procCommandFile string
runUserDir string
tmpPerUserDir string
}
func (env rootlessRuntimeDirEnvironmentImplementation) getProcCommandFile() string {
return env.procCommandFile
}
func (env rootlessRuntimeDirEnvironmentImplementation) getRunUserDir() string {
return env.runUserDir
}
func (env rootlessRuntimeDirEnvironmentImplementation) getTmpPerUserDir() string {
return env.tmpPerUserDir
}
func (rootlessRuntimeDirEnvironmentImplementation) homeDirGetRuntimeDir() (string, error) {
return homedir.GetRuntimeDir()
}
func (rootlessRuntimeDirEnvironmentImplementation) systemLstat(path string) (*system.StatT, error) {
return system.Lstat(path)
}
func (rootlessRuntimeDirEnvironmentImplementation) homedirGet() string {
return homedir.Get()
}
func isRootlessRuntimeDirOwner(dir string, env rootlessRuntimeDirEnvironment) bool {
st, err := env.systemLstat(dir)
return err == nil && int(st.UID()) == os.Getuid() && st.Mode()&0o700 == 0o700 && st.Mode()&0o066 == 0o000
}
// getRootlessRuntimeDirIsolated is an internal implementation detail of getRootlessRuntimeDir to allow testing.
// Everyone but the tests this is intended for should only call getRootlessRuntimeDir, never this function.
func getRootlessRuntimeDirIsolated(env rootlessRuntimeDirEnvironment) (string, error) {
runtimeDir, err := env.homeDirGetRuntimeDir()
if err == nil {
return runtimeDir, nil
}
initCommand, err := os.ReadFile(env.getProcCommandFile())
if err != nil || string(initCommand) == "systemd" {
runUserDir := env.getRunUserDir()
if isRootlessRuntimeDirOwner(runUserDir, env) {
return runUserDir, nil
}
}
tmpPerUserDir := env.getTmpPerUserDir()
if tmpPerUserDir != "" {
if _, err := env.systemLstat(tmpPerUserDir); os.IsNotExist(err) {
if err := os.Mkdir(tmpPerUserDir, 0o700); err != nil {
logrus.Errorf("Failed to create temp directory for user: %v", err)
} else {
return tmpPerUserDir, nil
}
} else if isRootlessRuntimeDirOwner(tmpPerUserDir, env) {
return tmpPerUserDir, nil
}
}
homeDir := env.homedirGet()
if homeDir == "" {
return "", errors.New("neither XDG_RUNTIME_DIR nor temp dir nor HOME was set non-empty")
}
resolvedHomeDir, err := filepath.EvalSymlinks(homeDir)
if err != nil {
return "", err
}
return filepath.Join(resolvedHomeDir, "rundir"), nil
}
func getRootlessRuntimeDir(rootlessUID int) (string, error) {
return getRootlessRuntimeDirIsolated(
rootlessRuntimeDirEnvironmentImplementation{
"/proc/1/comm",
fmt.Sprintf("/run/user/%d", rootlessUID),
fmt.Sprintf("%s/containers-user-%d", os.TempDir(), rootlessUID),
},
)
}
// getRootlessDirInfo returns the parent path of where the storage for containers and
// volumes will be in rootless mode
func getRootlessDirInfo(rootlessUID int) (string, string, error) {
rootlessRuntime, err := GetRootlessRuntimeDir(rootlessUID)
if err != nil {
return "", "", err
}
dataDir, err := homedir.GetDataHome()
if err == nil {
return dataDir, rootlessRuntime, nil
}
home := homedir.Get()
if home == "" {
return "", "", fmt.Errorf("neither XDG_DATA_HOME nor HOME was set non-empty: %w", err)
}
// runc doesn't like symlinks in the rootfs path, and at least
// on CoreOS /home is a symlink to /var/home, so resolve any symlink.
resolvedHome, err := filepath.EvalSymlinks(home)
if err != nil {
return "", "", err
}
dataDir = filepath.Join(resolvedHome, ".local", "share")
return dataDir, rootlessRuntime, nil
}
func getRootlessUID() int {
uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
if uidEnv != "" {
u, _ := strconv.Atoi(uidEnv)
return u
}
return os.Geteuid()
}
func expandEnvPath(path string, rootlessUID int) (string, error) {
var err error
path = strings.Replace(path, "$UID", strconv.Itoa(rootlessUID), -1)
@ -169,7 +22,7 @@ func expandEnvPath(path string, rootlessUID int) (string, error) {
return newpath, nil
}
func DefaultConfigFile(rootless bool) (string, error) {
func DefaultConfigFile() (string, error) {
if defaultConfigFileSet {
return defaultConfigFile, nil
}
@ -177,7 +30,7 @@ func DefaultConfigFile(rootless bool) (string, error) {
if path, ok := os.LookupEnv(storageConfEnv); ok {
return path, nil
}
if !rootless {
if !usePerUserStorage() {
if _, err := os.Stat(defaultOverrideConfigFile); err == nil {
return defaultOverrideConfigFile, nil
}

View File

@ -11,19 +11,9 @@ func ParseIDMapping(UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap stri
return types.ParseIDMapping(UIDMapSlice, GIDMapSlice, subUIDMap, subGIDMap)
}
// GetRootlessRuntimeDir returns the runtime directory when running as non root
func GetRootlessRuntimeDir(rootlessUID int) (string, error) {
return types.GetRootlessRuntimeDir(rootlessUID)
}
// DefaultStoreOptionsAutoDetectUID returns the default storage options for containers
func DefaultStoreOptionsAutoDetectUID() (types.StoreOptions, error) {
return types.DefaultStoreOptionsAutoDetectUID()
}
// DefaultStoreOptions returns the default storage options for containers
func DefaultStoreOptions(rootless bool, rootlessUID int) (types.StoreOptions, error) {
return types.DefaultStoreOptions(rootless, rootlessUID)
func DefaultStoreOptions() (types.StoreOptions, error) {
return types.DefaultStoreOptions()
}
func validateMountOptions(mountOptions []string) error {

6
vendor/modules.txt vendored
View File

@ -94,7 +94,7 @@ github.com/containernetworking/cni/pkg/version
# github.com/containernetworking/plugins v1.3.0
## explicit; go 1.20
github.com/containernetworking/plugins/pkg/ns
# github.com/containers/common v0.57.0
# github.com/containers/common v0.57.1-0.20231121115347-e2da7bec2245
## explicit; go 1.18
github.com/containers/common/internal/attributedstring
github.com/containers/common/libimage
@ -142,7 +142,7 @@ github.com/containers/common/pkg/umask
github.com/containers/common/pkg/util
github.com/containers/common/pkg/version
github.com/containers/common/version
# github.com/containers/image/v5 v5.29.0
# github.com/containers/image/v5 v5.29.1-0.20231120202631-293b00ba7166
## explicit; go 1.19
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
@ -233,7 +233,7 @@ github.com/containers/ocicrypt/keywrap/pkcs7
github.com/containers/ocicrypt/spec
github.com/containers/ocicrypt/utils
github.com/containers/ocicrypt/utils/keyprovider
# github.com/containers/storage v1.51.0
# github.com/containers/storage v1.51.1-0.20231120144510-2cf61989a5bc
## explicit; go 1.19
github.com/containers/storage
github.com/containers/storage/drivers