go.mod: update github.com/containers/image/v5
Version 5.22 introduced a new option to /etc/containers/policy.json called
keyPaths, see
https://github.com/containers/image/pull/1609
EL9 immediately took advantage of this new feature and started using it, see
04645c4a84
This quickly became an issue in our code: The go library (containers/image)
parses the configuration file very strictly and refuses to create a client
when policy.json with an unknown key is present on the filesystem. As we
used 5.21.1 that doesn't know the new key, our unit tests started to
failing when containers-common was present.
Reproducer:
podman run --pull=always --rm -it centos:stream9
dnf install -y dnf-plugins-core
dnf config-manager --set-enabled crb
dnf install -y gpgme-devel libassuan-devel krb5-devel golang git-core
git clone https://github.com/osbuild/osbuild-composer
cd osbuild-composer
# install the new containers-common and run the test
dnf install -y https://kojihub.stream.centos.org/kojifiles/packages/containers-common/1/44.el9/x86_64/containers-common-1-44.el9.x86_64.rpm
go test -count 1 ./...
# this returns:
--- FAIL: TestClientResolve (0.00s)
client_test.go:31:
Error Trace: client_test.go:31
Error: Received unexpected error:
Unknown key "keyPaths"
invalid policy in "/etc/containers/policy.json"
github.com/containers/image/v5/signature.NewPolicyFromFile
/osbuild-composer/vendor/github.com/containers/image/v5/signature/policy_config.go:88
github.com/osbuild/osbuild-composer/internal/container.NewClient
/osbuild-composer/internal/container/client.go:123
github.com/osbuild/osbuild-composer/internal/container_test.TestClientResolve
/osbuild-composer/internal/container/client_test.go:29
testing.tRunner
/usr/lib/golang/src/testing/testing.go:1439
runtime.goexit
/usr/lib/golang/src/runtime/asm_amd64.s:1571
Test: TestClientResolve
client_test.go:32:
Error Trace: client_test.go:32
Error: Expected value not to be nil.
Test: TestClientResolve
When run with an older containers-common, it succeeds:
dnf install -y https://kojihub.stream.centos.org/kojifiles/packages/containers-common/1/40.el9/x86_64/containers-common-1-40.el9.x86_64.rpm
go test -count 1 ./...
PASS
To sum it up, I had to upgrade github.com/containers/image/v5 to v5.22.0.
Unfortunately, this wasn't so simple, see
go get github.com/containers/image/v5@latest
go: github.com/containers/image/v5@v5.22.0 requires
github.com/letsencrypt/boulder@v0.0.0-20220331220046-b23ab962616e requires
github.com/honeycombio/beeline-go@v1.1.1 requires
github.com/gobuffalo/pop/v5@v5.3.1 requires
github.com/mattn/go-sqlite3@v2.0.3+incompatible: reading github.com/mattn/go-sqlite3/go.mod at revision v2.0.3: unknown revision v2.0.3
It turns out that github.com/mattn/go-sqlite3@v2.0.3+incompatible has been
recently retracted https://github.com/mattn/go-sqlite3/pull/998 and this
broke a ton of packages depending on it. I was able to fix it by adding
exclude github.com/mattn/go-sqlite3 v2.0.3+incompatible
to our go.mod, see
https://github.com/mattn/go-sqlite3/issues/975#issuecomment-955661657
After adding it,
go get github.com/containers/image/v5@latest
succeeded and tools/prepare-source.sh took care of the rest.
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
This commit is contained in:
parent
fa514c5326
commit
29f66a251f
694 changed files with 90636 additions and 50426 deletions
2
vendor/github.com/containers/storage/pkg/unshare/unshare.c
generated
vendored
2
vendor/github.com/containers/storage/pkg/unshare/unshare.c
generated
vendored
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef UNSHARE_NO_CODE_AT_ALL
|
||||
#if !defined(UNSHARE_NO_CODE_AT_ALL) && defined(__linux__)
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/types.h>
|
||||
|
|
|
|||
27
vendor/github.com/containers/storage/pkg/unshare/unshare.go
generated
vendored
27
vendor/github.com/containers/storage/pkg/unshare/unshare.go
generated
vendored
|
|
@ -6,8 +6,7 @@ import (
|
|||
"os/user"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/syndtr/gocapability/capability"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -27,7 +26,7 @@ func HomeDir() (string, error) {
|
|||
if home == "" {
|
||||
usr, err := user.LookupId(fmt.Sprintf("%d", GetRootlessUID()))
|
||||
if err != nil {
|
||||
homeDir, homeDirErr = "", errors.Wrapf(err, "unable to resolve HOME directory")
|
||||
homeDir, homeDirErr = "", fmt.Errorf("unable to resolve HOME directory: %w", err)
|
||||
return
|
||||
}
|
||||
homeDir, homeDirErr = usr.HomeDir, nil
|
||||
|
|
@ -38,19 +37,13 @@ func HomeDir() (string, error) {
|
|||
return homeDir, homeDirErr
|
||||
}
|
||||
|
||||
// HasCapSysAdmin returns whether the current process has CAP_SYS_ADMIN.
|
||||
func HasCapSysAdmin() (bool, error) {
|
||||
hasCapSysAdminOnce.Do(func() {
|
||||
currentCaps, err := capability.NewPid2(0)
|
||||
if err != nil {
|
||||
hasCapSysAdminErr = err
|
||||
return
|
||||
func bailOnError(err error, format string, a ...interface{}) { // nolint: golint,goprintffuncname
|
||||
if err != nil {
|
||||
if format != "" {
|
||||
logrus.Errorf("%s: %v", fmt.Sprintf(format, a...), err)
|
||||
} else {
|
||||
logrus.Errorf("%v", err)
|
||||
}
|
||||
if err = currentCaps.Load(); err != nil {
|
||||
hasCapSysAdminErr = err
|
||||
return
|
||||
}
|
||||
hasCapSysAdminRet = currentCaps.Get(capability.EFFECTIVE, capability.CAP_SYS_ADMIN)
|
||||
})
|
||||
return hasCapSysAdminRet, hasCapSysAdminErr
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
vendor/github.com/containers/storage/pkg/unshare/unshare_cgo.go
generated
vendored
3
vendor/github.com/containers/storage/pkg/unshare/unshare_cgo.go
generated
vendored
|
|
@ -1,4 +1,5 @@
|
|||
// +build linux,cgo,!gccgo
|
||||
//go:build (linux && cgo && !gccgo) || (freebsd && cgo)
|
||||
// +build linux,cgo,!gccgo freebsd,cgo
|
||||
|
||||
package unshare
|
||||
|
||||
|
|
|
|||
53
vendor/github.com/containers/storage/pkg/unshare/unshare_darwin.go
generated
vendored
Normal file
53
vendor/github.com/containers/storage/pkg/unshare/unshare_darwin.go
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// +build darwin
|
||||
|
||||
package unshare
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
const (
|
||||
// UsernsEnvName is the environment variable, if set indicates in rootless mode
|
||||
UsernsEnvName = "_CONTAINERS_USERNS_CONFIGURED"
|
||||
)
|
||||
|
||||
// IsRootless tells us if we are running in rootless mode
|
||||
func IsRootless() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetRootlessUID returns the UID of the user in the parent userNS
|
||||
func GetRootlessUID() int {
|
||||
return os.Getuid()
|
||||
}
|
||||
|
||||
// RootlessEnv returns the environment settings for the rootless containers
|
||||
func RootlessEnv() []string {
|
||||
return append(os.Environ(), UsernsEnvName+"=")
|
||||
}
|
||||
|
||||
// MaybeReexecUsingUserNamespace re-exec the process in a new namespace
|
||||
func MaybeReexecUsingUserNamespace(evenForRoot bool) {
|
||||
}
|
||||
|
||||
// GetHostIDMappings reads mappings for the specified process (or the current
|
||||
// process if pid is "self" or an empty string) from the kernel.
|
||||
func GetHostIDMappings(pid string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
// ParseIDMappings parses mapping triples.
|
||||
func ParseIDMappings(uidmap, gidmap []string) ([]idtools.IDMap, []idtools.IDMap, error) {
|
||||
uid, err := idtools.ParseIDMap(uidmap, "userns-uid-map")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
gid, err := idtools.ParseIDMap(gidmap, "userns-gid-map")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return uid, gid, nil
|
||||
}
|
||||
76
vendor/github.com/containers/storage/pkg/unshare/unshare_freebsd.c
generated
vendored
Normal file
76
vendor/github.com/containers/storage/pkg/unshare/unshare_freebsd.c
generated
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#if !defined(UNSHARE_NO_CODE_AT_ALL) && defined(__FreeBSD__)
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int _containers_unshare_parse_envint(const char *envname) {
|
||||
char *p, *q;
|
||||
long l;
|
||||
|
||||
p = getenv(envname);
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
q = NULL;
|
||||
l = strtol(p, &q, 10);
|
||||
if ((q == NULL) || (*q != '\0')) {
|
||||
fprintf(stderr, "Error parsing \"%s\"=\"%s\"!\n", envname, p);
|
||||
_exit(1);
|
||||
}
|
||||
unsetenv(envname);
|
||||
return l;
|
||||
}
|
||||
|
||||
void _containers_unshare(void)
|
||||
{
|
||||
int pidfd, continuefd, n, pgrp, sid, ctty;
|
||||
char buf[2048];
|
||||
|
||||
pidfd = _containers_unshare_parse_envint("_Containers-pid-pipe");
|
||||
if (pidfd != -1) {
|
||||
snprintf(buf, sizeof(buf), "%llu", (unsigned long long) getpid());
|
||||
size_t size = write(pidfd, buf, strlen(buf));
|
||||
if (size != strlen(buf)) {
|
||||
fprintf(stderr, "Error writing PID to pipe on fd %d: %m\n", pidfd);
|
||||
_exit(1);
|
||||
}
|
||||
close(pidfd);
|
||||
}
|
||||
continuefd = _containers_unshare_parse_envint("_Containers-continue-pipe");
|
||||
if (continuefd != -1) {
|
||||
n = read(continuefd, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
fprintf(stderr, "Error: %.*s\n", n, buf);
|
||||
_exit(1);
|
||||
}
|
||||
close(continuefd);
|
||||
}
|
||||
sid = _containers_unshare_parse_envint("_Containers-setsid");
|
||||
if (sid == 1) {
|
||||
if (setsid() == -1) {
|
||||
fprintf(stderr, "Error during setsid: %m\n");
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
pgrp = _containers_unshare_parse_envint("_Containers-setpgrp");
|
||||
if (pgrp == 1) {
|
||||
if (setpgrp(0, 0) == -1) {
|
||||
fprintf(stderr, "Error during setpgrp: %m\n");
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
ctty = _containers_unshare_parse_envint("_Containers-ctty");
|
||||
if (ctty != -1) {
|
||||
if (ioctl(ctty, TIOCSCTTY, 0) == -1) {
|
||||
fprintf(stderr, "Error while setting controlling terminal to %d: %m\n", ctty);
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
179
vendor/github.com/containers/storage/pkg/unshare/unshare_freebsd.go
generated
vendored
Normal file
179
vendor/github.com/containers/storage/pkg/unshare/unshare_freebsd.go
generated
vendored
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
//go:build freebsd
|
||||
// +build freebsd
|
||||
|
||||
package unshare
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/storage/pkg/reexec"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Cmd wraps an exec.Cmd created by the reexec package in unshare(),
|
||||
// and one day might handle setting ID maps and other related setting*s
|
||||
// by triggering initialization code in the child.
|
||||
type Cmd struct {
|
||||
*exec.Cmd
|
||||
Setsid bool
|
||||
Setpgrp bool
|
||||
Ctty *os.File
|
||||
Hook func(pid int) error
|
||||
}
|
||||
|
||||
// Command creates a new Cmd which can be customized.
|
||||
func Command(args ...string) *Cmd {
|
||||
cmd := reexec.Command(args...)
|
||||
return &Cmd{
|
||||
Cmd: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cmd) Start() error {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
// Set environment variables to tell the child to synchronize its startup.
|
||||
if c.Env == nil {
|
||||
c.Env = os.Environ()
|
||||
}
|
||||
|
||||
// Create the pipe for reading the child's PID.
|
||||
pidRead, pidWrite, err := os.Pipe()
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating pid pipe: %w", err)
|
||||
}
|
||||
c.Env = append(c.Env, fmt.Sprintf("_Containers-pid-pipe=%d", len(c.ExtraFiles)+3))
|
||||
c.ExtraFiles = append(c.ExtraFiles, pidWrite)
|
||||
|
||||
// Create the pipe for letting the child know to proceed.
|
||||
continueRead, continueWrite, err := os.Pipe()
|
||||
if err != nil {
|
||||
pidRead.Close()
|
||||
pidWrite.Close()
|
||||
return fmt.Errorf("creating pid pipe: %w", err)
|
||||
}
|
||||
c.Env = append(c.Env, fmt.Sprintf("_Containers-continue-pipe=%d", len(c.ExtraFiles)+3))
|
||||
c.ExtraFiles = append(c.ExtraFiles, continueRead)
|
||||
|
||||
// Pass along other instructions.
|
||||
if c.Setsid {
|
||||
c.Env = append(c.Env, "_Containers-setsid=1")
|
||||
}
|
||||
if c.Setpgrp {
|
||||
c.Env = append(c.Env, "_Containers-setpgrp=1")
|
||||
}
|
||||
if c.Ctty != nil {
|
||||
c.Env = append(c.Env, fmt.Sprintf("_Containers-ctty=%d", len(c.ExtraFiles)+3))
|
||||
c.ExtraFiles = append(c.ExtraFiles, c.Ctty)
|
||||
}
|
||||
|
||||
// Make sure we clean up our pipes.
|
||||
defer func() {
|
||||
if pidRead != nil {
|
||||
pidRead.Close()
|
||||
}
|
||||
if pidWrite != nil {
|
||||
pidWrite.Close()
|
||||
}
|
||||
if continueRead != nil {
|
||||
continueRead.Close()
|
||||
}
|
||||
if continueWrite != nil {
|
||||
continueWrite.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
// Start the new process.
|
||||
err = c.Cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Close the ends of the pipes that the parent doesn't need.
|
||||
continueRead.Close()
|
||||
continueRead = nil
|
||||
pidWrite.Close()
|
||||
pidWrite = nil
|
||||
|
||||
// Read the child's PID from the pipe.
|
||||
pidString := ""
|
||||
b := new(bytes.Buffer)
|
||||
if _, err := io.Copy(b, pidRead); err != nil {
|
||||
return fmt.Errorf("reading child PID: %w", err)
|
||||
}
|
||||
pidString = b.String()
|
||||
pid, err := strconv.Atoi(pidString)
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "error parsing PID %q: %v", pidString, err)
|
||||
return fmt.Errorf("parsing PID %q: %w", pidString, err)
|
||||
}
|
||||
|
||||
// Run any additional setup that we want to do before the child starts running proper.
|
||||
if c.Hook != nil {
|
||||
if err = c.Hook(pid); err != nil {
|
||||
fmt.Fprintf(continueWrite, "hook error: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cmd) Run() error {
|
||||
if err := c.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Wait()
|
||||
}
|
||||
|
||||
func (c *Cmd) CombinedOutput() ([]byte, error) {
|
||||
return nil, errors.New("unshare: CombinedOutput() not implemented")
|
||||
}
|
||||
|
||||
func (c *Cmd) Output() ([]byte, error) {
|
||||
return nil, errors.New("unshare: Output() not implemented")
|
||||
}
|
||||
|
||||
type Runnable interface {
|
||||
Run() error
|
||||
}
|
||||
|
||||
// ExecRunnable runs the specified unshare command, captures its exit status,
|
||||
// and exits with the same status.
|
||||
func ExecRunnable(cmd Runnable, cleanup func()) {
|
||||
exit := func(status int) {
|
||||
if cleanup != nil {
|
||||
cleanup()
|
||||
}
|
||||
os.Exit(status)
|
||||
}
|
||||
if err := cmd.Run(); err != nil {
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
if exitError.ProcessState.Exited() {
|
||||
if waitStatus, ok := exitError.ProcessState.Sys().(syscall.WaitStatus); ok {
|
||||
if waitStatus.Exited() {
|
||||
logrus.Debugf("%v", exitError)
|
||||
exit(waitStatus.ExitStatus())
|
||||
}
|
||||
if waitStatus.Signaled() {
|
||||
logrus.Debugf("%v", exitError)
|
||||
exit(int(waitStatus.Signal()) + 128)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logrus.Errorf("%v", err)
|
||||
logrus.Errorf("(Unable to determine exit status)")
|
||||
exit(1)
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
90
vendor/github.com/containers/storage/pkg/unshare/unshare_linux.go
generated
vendored
90
vendor/github.com/containers/storage/pkg/unshare/unshare_linux.go
generated
vendored
|
|
@ -6,6 +6,7 @@ package unshare
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
|
@ -21,7 +22,6 @@ import (
|
|||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/reexec"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/syndtr/gocapability/capability"
|
||||
)
|
||||
|
|
@ -78,7 +78,7 @@ func getRootlessGID() int {
|
|||
}
|
||||
|
||||
// IsSetID checks if specified path has correct FileMode (Setuid|SETGID) or the
|
||||
// matching file capabilitiy
|
||||
// matching file capability
|
||||
func IsSetID(path string, modeid os.FileMode, capid capability.Cap) (bool, error) {
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
|
|
@ -119,7 +119,7 @@ func (c *Cmd) Start() error {
|
|||
// Create the pipe for reading the child's PID.
|
||||
pidRead, pidWrite, err := os.Pipe()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error creating pid pipe")
|
||||
return fmt.Errorf("creating pid pipe: %w", err)
|
||||
}
|
||||
c.Env = append(c.Env, fmt.Sprintf("_Containers-pid-pipe=%d", len(c.ExtraFiles)+3))
|
||||
c.ExtraFiles = append(c.ExtraFiles, pidWrite)
|
||||
|
|
@ -129,7 +129,7 @@ func (c *Cmd) Start() error {
|
|||
if err != nil {
|
||||
pidRead.Close()
|
||||
pidWrite.Close()
|
||||
return errors.Wrapf(err, "error creating pid pipe")
|
||||
return fmt.Errorf("creating pid pipe: %w", err)
|
||||
}
|
||||
c.Env = append(c.Env, fmt.Sprintf("_Containers-continue-pipe=%d", len(c.ExtraFiles)+3))
|
||||
c.ExtraFiles = append(c.ExtraFiles, continueRead)
|
||||
|
|
@ -178,13 +178,13 @@ func (c *Cmd) Start() error {
|
|||
pidString := ""
|
||||
b := new(bytes.Buffer)
|
||||
if _, err := io.Copy(b, pidRead); err != nil {
|
||||
return errors.Wrapf(err, "Reading child PID")
|
||||
return fmt.Errorf("reading child PID: %w", err)
|
||||
}
|
||||
pidString = b.String()
|
||||
pid, err := strconv.Atoi(pidString)
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "error parsing PID %q: %v", pidString, err)
|
||||
return errors.Wrapf(err, "error parsing PID %q", pidString)
|
||||
return fmt.Errorf("parsing PID %q: %w", pidString, err)
|
||||
}
|
||||
pidString = fmt.Sprintf("%d", pid)
|
||||
|
||||
|
|
@ -194,26 +194,26 @@ func (c *Cmd) Start() error {
|
|||
setgroups, err := os.OpenFile(fmt.Sprintf("/proc/%s/setgroups", pidString), os.O_TRUNC|os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "error opening setgroups: %v", err)
|
||||
return errors.Wrapf(err, "error opening /proc/%s/setgroups", pidString)
|
||||
return fmt.Errorf("opening /proc/%s/setgroups: %w", pidString, err)
|
||||
}
|
||||
defer setgroups.Close()
|
||||
if c.GidMappingsEnableSetgroups {
|
||||
if _, err := fmt.Fprintf(setgroups, "allow"); err != nil {
|
||||
fmt.Fprintf(continueWrite, "error writing \"allow\" to setgroups: %v", err)
|
||||
return errors.Wrapf(err, "error opening \"allow\" to /proc/%s/setgroups", pidString)
|
||||
return fmt.Errorf("opening \"allow\" to /proc/%s/setgroups: %w", pidString, err)
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprintf(setgroups, "deny"); err != nil {
|
||||
fmt.Fprintf(continueWrite, "error writing \"deny\" to setgroups: %v", err)
|
||||
return errors.Wrapf(err, "error writing \"deny\" to /proc/%s/setgroups", pidString)
|
||||
return fmt.Errorf("writing \"deny\" to /proc/%s/setgroups: %w", pidString, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(c.UidMappings) == 0 || len(c.GidMappings) == 0 {
|
||||
uidmap, gidmap, err := GetHostIDMappings("")
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "Reading ID mappings in parent: %v", err)
|
||||
return errors.Wrapf(err, "Reading ID mappings in parent")
|
||||
fmt.Fprintf(continueWrite, "error reading ID mappings in parent: %v", err)
|
||||
return fmt.Errorf("reading ID mappings in parent: %w", err)
|
||||
}
|
||||
if len(c.UidMappings) == 0 {
|
||||
c.UidMappings = uidmap
|
||||
|
|
@ -240,7 +240,7 @@ func (c *Cmd) Start() error {
|
|||
if c.UseNewgidmap {
|
||||
path, err := exec.LookPath("newgidmap")
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error finding newgidmap")
|
||||
return fmt.Errorf("finding newgidmap: %w", err)
|
||||
}
|
||||
cmd := exec.Command(path, append([]string{pidString}, strings.Fields(strings.Replace(g.String(), "\n", " ", -1))...)...)
|
||||
g.Reset()
|
||||
|
|
@ -249,7 +249,7 @@ func (c *Cmd) Start() error {
|
|||
if err := cmd.Run(); err == nil {
|
||||
gidmapSet = true
|
||||
} else {
|
||||
logrus.Warnf("Error running newgidmap: %v: %s", err, g.String())
|
||||
logrus.Warnf("running newgidmap: %v: %s", err, g.String())
|
||||
isSetgid, err := IsSetID(path, os.ModeSetgid, capability.CAP_SETGID)
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to check for setgid on %s: %v", path, err)
|
||||
|
|
@ -268,23 +268,23 @@ func (c *Cmd) Start() error {
|
|||
setgroups, err := os.OpenFile(fmt.Sprintf("/proc/%s/setgroups", pidString), os.O_TRUNC|os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "error opening /proc/%s/setgroups: %v", pidString, err)
|
||||
return errors.Wrapf(err, "error opening /proc/%s/setgroups", pidString)
|
||||
return fmt.Errorf("opening /proc/%s/setgroups: %w", pidString, err)
|
||||
}
|
||||
defer setgroups.Close()
|
||||
if _, err := fmt.Fprintf(setgroups, "deny"); err != nil {
|
||||
fmt.Fprintf(continueWrite, "error writing 'deny' to /proc/%s/setgroups: %v", pidString, err)
|
||||
return errors.Wrapf(err, "error writing 'deny' to /proc/%s/setgroups", pidString)
|
||||
return fmt.Errorf("writing 'deny' to /proc/%s/setgroups: %w", pidString, err)
|
||||
}
|
||||
}
|
||||
gidmap, err := os.OpenFile(fmt.Sprintf("/proc/%s/gid_map", pidString), os.O_TRUNC|os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "error opening /proc/%s/gid_map: %v", pidString, err)
|
||||
return errors.Wrapf(err, "error opening /proc/%s/gid_map", pidString)
|
||||
fmt.Fprintf(continueWrite, "opening /proc/%s/gid_map: %v", pidString, err)
|
||||
return fmt.Errorf("opening /proc/%s/gid_map: %w", pidString, err)
|
||||
}
|
||||
defer gidmap.Close()
|
||||
if _, err := fmt.Fprintf(gidmap, "%s", g.String()); err != nil {
|
||||
fmt.Fprintf(continueWrite, "error writing %q to /proc/%s/gid_map: %v", g.String(), pidString, err)
|
||||
return errors.Wrapf(err, "error writing %q to /proc/%s/gid_map", g.String(), pidString)
|
||||
fmt.Fprintf(continueWrite, "writing %q to /proc/%s/gid_map: %v", g.String(), pidString, err)
|
||||
return fmt.Errorf("writing %q to /proc/%s/gid_map: %w", g.String(), pidString, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -300,7 +300,7 @@ func (c *Cmd) Start() error {
|
|||
if c.UseNewuidmap {
|
||||
path, err := exec.LookPath("newuidmap")
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error finding newuidmap")
|
||||
return fmt.Errorf("finding newuidmap: %w", err)
|
||||
}
|
||||
cmd := exec.Command(path, append([]string{pidString}, strings.Fields(strings.Replace(u.String(), "\n", " ", -1))...)...)
|
||||
u.Reset()
|
||||
|
|
@ -328,12 +328,12 @@ func (c *Cmd) Start() error {
|
|||
uidmap, err := os.OpenFile(fmt.Sprintf("/proc/%s/uid_map", pidString), os.O_TRUNC|os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "error opening /proc/%s/uid_map: %v", pidString, err)
|
||||
return errors.Wrapf(err, "error opening /proc/%s/uid_map", pidString)
|
||||
return fmt.Errorf("opening /proc/%s/uid_map: %w", pidString, err)
|
||||
}
|
||||
defer uidmap.Close()
|
||||
if _, err := fmt.Fprintf(uidmap, "%s", u.String()); err != nil {
|
||||
fmt.Fprintf(continueWrite, "error writing %q to /proc/%s/uid_map: %v", u.String(), pidString, err)
|
||||
return errors.Wrapf(err, "error writing %q to /proc/%s/uid_map", u.String(), pidString)
|
||||
return fmt.Errorf("writing %q to /proc/%s/uid_map: %w", u.String(), pidString, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -343,12 +343,12 @@ func (c *Cmd) Start() error {
|
|||
oomScoreAdj, err := os.OpenFile(fmt.Sprintf("/proc/%s/oom_score_adj", pidString), os.O_TRUNC|os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "error opening oom_score_adj: %v", err)
|
||||
return errors.Wrapf(err, "error opening /proc/%s/oom_score_adj", pidString)
|
||||
return fmt.Errorf("opening /proc/%s/oom_score_adj: %w", pidString, err)
|
||||
}
|
||||
defer oomScoreAdj.Close()
|
||||
if _, err := fmt.Fprintf(oomScoreAdj, "%d\n", *c.OOMScoreAdj); err != nil {
|
||||
fmt.Fprintf(continueWrite, "error writing \"%d\" to oom_score_adj: %v", c.OOMScoreAdj, err)
|
||||
return errors.Wrapf(err, "error writing \"%d\" to /proc/%s/oom_score_adj", c.OOMScoreAdj, pidString)
|
||||
return fmt.Errorf("writing \"%d\" to /proc/%s/oom_score_adj: %w", c.OOMScoreAdj, pidString, err)
|
||||
}
|
||||
}
|
||||
// Run any additional setup that we want to do before the child starts running proper.
|
||||
|
|
@ -414,17 +414,6 @@ type Runnable interface {
|
|||
Run() error
|
||||
}
|
||||
|
||||
func bailOnError(err error, format string, a ...interface{}) { // nolint: golint,goprintffuncname
|
||||
if err != nil {
|
||||
if format != "" {
|
||||
logrus.Errorf("%s: %v", fmt.Sprintf(format, a...), err)
|
||||
} else {
|
||||
logrus.Errorf("%v", err)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// MaybeReexecUsingUserNamespace re-exec the process in a new namespace
|
||||
func MaybeReexecUsingUserNamespace(evenForRoot bool) {
|
||||
// If we've already been through this once, no need to try again.
|
||||
|
|
@ -568,7 +557,7 @@ func ExecRunnable(cmd Runnable, cleanup func()) {
|
|||
os.Exit(status)
|
||||
}
|
||||
if err := cmd.Run(); err != nil {
|
||||
if exitError, ok := errors.Cause(err).(*exec.ExitError); ok {
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
if exitError.ProcessState.Exited() {
|
||||
if waitStatus, ok := exitError.ProcessState.Sys().(syscall.WaitStatus); ok {
|
||||
if waitStatus.Exited() {
|
||||
|
|
@ -594,7 +583,7 @@ func getHostIDMappings(path string) ([]specs.LinuxIDMapping, error) {
|
|||
var mappings []specs.LinuxIDMapping
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Reading ID mappings from %q", path)
|
||||
return nil, fmt.Errorf("reading ID mappings from %q: %w", path, err)
|
||||
}
|
||||
defer f.Close()
|
||||
scanner := bufio.NewScanner(f)
|
||||
|
|
@ -602,19 +591,19 @@ func getHostIDMappings(path string) ([]specs.LinuxIDMapping, error) {
|
|||
line := scanner.Text()
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) != 3 {
|
||||
return nil, errors.Errorf("line %q from %q has %d fields, not 3", line, path, len(fields))
|
||||
return nil, fmt.Errorf("line %q from %q has %d fields, not 3", line, path, len(fields))
|
||||
}
|
||||
cid, err := strconv.ParseUint(fields[0], 10, 32)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error parsing container ID value %q from line %q in %q", fields[0], line, path)
|
||||
return nil, fmt.Errorf("parsing container ID value %q from line %q in %q: %w", fields[0], line, path, err)
|
||||
}
|
||||
hid, err := strconv.ParseUint(fields[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error parsing host ID value %q from line %q in %q", fields[1], line, path)
|
||||
return nil, fmt.Errorf("parsing host ID value %q from line %q in %q: %w", fields[1], line, path, err)
|
||||
}
|
||||
size, err := strconv.ParseUint(fields[2], 10, 32)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error parsing size value %q from line %q in %q", fields[2], line, path)
|
||||
return nil, fmt.Errorf("parsing size value %q from line %q in %q: %w", fields[2], line, path, err)
|
||||
}
|
||||
mappings = append(mappings, specs.LinuxIDMapping{ContainerID: uint32(cid), HostID: uint32(hid), Size: uint32(size)})
|
||||
}
|
||||
|
|
@ -642,7 +631,7 @@ func GetHostIDMappings(pid string) ([]specs.LinuxIDMapping, []specs.LinuxIDMappi
|
|||
func GetSubIDMappings(user, group string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) {
|
||||
mappings, err := idtools.NewIDMappings(user, group)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "Reading subuid mappings for user %q and subgid mappings for group %q", user, group)
|
||||
return nil, nil, fmt.Errorf("reading subuid mappings for user %q and subgid mappings for group %q: %w", user, group, err)
|
||||
}
|
||||
var uidmap, gidmap []specs.LinuxIDMapping
|
||||
for _, m := range mappings.UIDs() {
|
||||
|
|
@ -674,3 +663,20 @@ func ParseIDMappings(uidmap, gidmap []string) ([]idtools.IDMap, []idtools.IDMap,
|
|||
}
|
||||
return uid, gid, nil
|
||||
}
|
||||
|
||||
// HasCapSysAdmin returns whether the current process has CAP_SYS_ADMIN.
|
||||
func HasCapSysAdmin() (bool, error) {
|
||||
hasCapSysAdminOnce.Do(func() {
|
||||
currentCaps, err := capability.NewPid2(0)
|
||||
if err != nil {
|
||||
hasCapSysAdminErr = err
|
||||
return
|
||||
}
|
||||
if err = currentCaps.Load(); err != nil {
|
||||
hasCapSysAdminErr = err
|
||||
return
|
||||
}
|
||||
hasCapSysAdminRet = currentCaps.Get(capability.EFFECTIVE, capability.CAP_SYS_ADMIN)
|
||||
})
|
||||
return hasCapSysAdminRet, hasCapSysAdminErr
|
||||
}
|
||||
|
|
|
|||
8
vendor/github.com/containers/storage/pkg/unshare/unshare_unsupported.go
generated
vendored
8
vendor/github.com/containers/storage/pkg/unshare/unshare_unsupported.go
generated
vendored
|
|
@ -1,4 +1,5 @@
|
|||
// +build !linux
|
||||
//go:build !linux && !darwin
|
||||
// +build !linux,!darwin
|
||||
|
||||
package unshare
|
||||
|
||||
|
|
@ -43,3 +44,8 @@ func GetHostIDMappings(pid string) ([]specs.LinuxIDMapping, []specs.LinuxIDMappi
|
|||
func ParseIDMappings(uidmap, gidmap []string) ([]idtools.IDMap, []idtools.IDMap, error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
// HasCapSysAdmin returns whether the current process has CAP_SYS_ADMIN.
|
||||
func HasCapSysAdmin() (bool, error) {
|
||||
return os.Geteuid() == 0, nil
|
||||
}
|
||||
|
|
|
|||
3
vendor/github.com/containers/storage/pkg/unshare/unshare_unsupported_cgo.go
generated
vendored
3
vendor/github.com/containers/storage/pkg/unshare/unshare_unsupported_cgo.go
generated
vendored
|
|
@ -1,4 +1,5 @@
|
|||
// +build !linux,cgo
|
||||
//go:build cgo && !(linux || freebsd)
|
||||
// +build cgo,!linux,!freebsd
|
||||
|
||||
package unshare
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue