Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rootlesskit for openSUSE:Factory checked in at 2023-01-09 17:24:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rootlesskit (Old) and /work/SRC/openSUSE:Factory/.rootlesskit.new.32243 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rootlesskit" Mon Jan 9 17:24:04 2023 rev:3 rq:1057014 version:1.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/rootlesskit/rootlesskit.changes 2022-04-22 21:56:23.090951662 +0200 +++ /work/SRC/openSUSE:Factory/.rootlesskit.new.32243/rootlesskit.changes 2023-01-09 17:24:04.907253250 +0100 @@ -1,0 +2,11 @@ +Sat Dec 24 16:43:43 UTC 2022 - [email protected] + +- Update to version 1.1.0: + * Support using /usr/bin/getsubids (`--subid-source=dynamic`) + Useful for SSSD environments (subid: sss in /etc/nsswitch.conf) + + Full changes: https://github.com/rootless-containers/rootlesskit/milestone/3?closed=1 + +- bump vendor dependencies + +------------------------------------------------------------------- Old: ---- rootlesskit-1.0.0.tar.gz New: ---- rootlesskit-1.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rootlesskit.spec ++++++ --- /var/tmp/diff_new_pack.1xNYWB/_old 2023-01-09 17:24:05.475256464 +0100 +++ /var/tmp/diff_new_pack.1xNYWB/_new 2023-01-09 17:24:05.479256487 +0100 @@ -24,7 +24,7 @@ %global import_path %{provider_prefix} Name: rootlesskit -Version: 1.0.0 +Version: 1.1.0 Release: 0 Summary: Linux-native fakeroot using user namespaces License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.1xNYWB/_old 2023-01-09 17:24:05.511256667 +0100 +++ /var/tmp/diff_new_pack.1xNYWB/_new 2023-01-09 17:24:05.515256690 +0100 @@ -4,7 +4,7 @@ <param name="url">https://github.com/rootless-containers/rootlesskit.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v1.0.0</param> + <param name="revision">v1.1.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.1xNYWB/_old 2023-01-09 17:24:05.531256781 +0100 +++ /var/tmp/diff_new_pack.1xNYWB/_new 2023-01-09 17:24:05.535256803 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/rootless-containers/rootlesskit.git</param> - <param name="changesrevision">1920341cd41e047834a21007424162a2dc946315</param></service></servicedata> + <param name="changesrevision">6222b477d4c3ce6eea2bcff0586e43c95d1c0bb7</param></service></servicedata> (No newline at EOF) ++++++ rootlesskit-1.0.0.tar.gz -> rootlesskit-1.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/.github/workflows/main.yaml new/rootlesskit-1.1.0/.github/workflows/main.yaml --- old/rootlesskit-1.0.0/.github/workflows/main.yaml 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/.github/workflows/main.yaml 2022-11-15 12:09:45.000000000 +0100 @@ -11,6 +11,13 @@ run: DOCKER_BUILDKIT=1 docker build -t rootlesskit:test-unit --target test-unit . - name: "Unit test" run: docker run --rm --privileged rootlesskit:test-unit + test-cross: + name: "Cross compilation test" + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v3 + - name: "Build binaries" + run: DOCKER_BUILDKIT=1 docker build -o /tmp/artifact --target cross-artifact . test-integration: name: "Integration test" runs-on: ubuntu-latest @@ -93,8 +100,7 @@ - name: "Check out" uses: actions/checkout@v3 - name: "Build integration test image" - # Docker 20.10.x builds RootlessKit with Go 1.16 (as of Docker 20.10.14), so we use Go 1.16 as well here. - run: DOCKER_BUILDKIT=1 docker build -t rootlesskit:test-integration-docker --target test-integration-docker --build-arg GO_VERSION=1.16 . + run: DOCKER_BUILDKIT=1 docker build -t rootlesskit:test-integration-docker --target test-integration-docker --build-arg GO_VERSION=1.18 . - name: "Create a custom network to avoid IP confusion" run: docker network create custom - name: "Docker Integration test: net=slirp4netns, port-driver=builtin" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/Dockerfile new/rootlesskit-1.1.0/Dockerfile --- old/rootlesskit-1.0.0/Dockerfile 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/Dockerfile 2022-11-15 12:09:45.000000000 +0100 @@ -1,9 +1,9 @@ -ARG GO_VERSION=1.18 +ARG GO_VERSION=1.19 ARG UBUNTU_VERSION=20.04 ARG SHADOW_VERSION=4.8.1 -ARG SLIRP4NETNS_VERSION=v1.1.12 +ARG SLIRP4NETNS_VERSION=v1.2.0 ARG VPNKIT_VERSION=0.5.0 -ARG DOCKER_VERSION=20.10.14 +ARG DOCKER_VERSION=20.10.21 FROM golang:${GO_VERSION}-alpine AS build RUN apk add --no-cache file git make diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/README.md new/rootlesskit-1.1.0/README.md --- old/rootlesskit-1.0.0/README.md 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/README.md 2022-11-15 12:09:45.000000000 +0100 @@ -51,6 +51,7 @@ * [Docker/Moby](https://get.docker.com/rootless) * [Podman](https://podman.io/) (since Podman v1.8.0) * [nerdctl](https://github.com/containerd/nerdctl): Docker-compatible CLI for containerd +* [iSulad](https://github.com/openeuler-mirror/iSulad/tree/master/docs/manual/rootless.md): a lightweight container engine Container image builders: * [BuildKit](https://github.com/moby/buildkit): Next-generation `docker build` backend @@ -153,74 +154,78 @@ rootlesskit [global options] [arguments...] VERSION: - 0.14.0-beta.0 + 1.1.0 DESCRIPTION: RootlessKit is a Linux-native implementation of "fake root" using user_namespaces(7). - + Web site: https://github.com/rootless-containers/rootlesskit - + Examples: # spawn a shell with a new user namespace and a mount namespace rootlesskit bash - + # make /etc writable rootlesskit --copy-up=/etc bash - + # set mount propagation to rslave rootlesskit --propagation=rslave bash - + # create a network namespace with slirp4netns, and expose 80/tcp on the namespace as 8080/tcp on the host rootlesskit --copy-up=/etc --net=slirp4netns --disable-host-loopback --port-driver=builtin -p 127.0.0.1:8080:80/tcp bash - + Note: RootlessKit requires /etc/subuid and /etc/subgid to be configured by the real root user. See https://rootlesscontaine.rs/getting-started/common/ . OPTIONS: - Misc: - --debug debug mode (default: false) - --help, -h show help (default: false) - --version, -v print the version (default: false) - - Mount: - --copy-up value mount a filesystem and copy-up the contents. e.g. "--copy-up=/etc" (typically required for non-host network) - --copy-up-mode value copy-up mode [tmpfs+symlink] (default: "tmpfs+symlink") - --propagation value mount propagation [rprivate, rslave] (default: "rprivate") - - Network: - --net value network driver [host, slirp4netns, vpnkit, lxc-user-nic(experimental)] (default: "host") - --mtu value MTU for non-host network (default: 65520 for slirp4netns, 1500 for others) (default: 0) - --cidr value CIDR for slirp4netns network (default: 10.0.2.0/24) - --ifname value Network interface name (default: tap0 for slirp4netns and vpnkit, eth0 for lxc-user-nic) - --disable-host-loopback prohibit connecting to 127.0.0.1:* on the host namespace (default: false) - - Network [lxc-user-nic]: - --lxc-user-nic-binary value path of lxc-user-nic binary for --net=lxc-user-nic (default: "/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic") - --lxc-user-nic-bridge value lxc-user-nic bridge name (default: "lxcbr0") - - Network [slirp4netns]: - --slirp4netns-binary value path of slirp4netns binary for --net=slirp4netns (default: "slirp4netns") - --slirp4netns-sandbox value enable slirp4netns sandbox (experimental) [auto, true, false] (the default is planned to be "auto" in future) (default: "false") - --slirp4netns-seccomp value enable slirp4netns seccomp (experimental) [auto, true, false] (the default is planned to be "auto" in future) (default: "false") - - Network [vpnkit]: - --vpnkit-binary value path of VPNKit binary for --net=vpnkit (default: "vpnkit") - - Port: - --port-driver value port driver for non-host network. [none, builtin, slirp4netns] (default: "none") - --publish value, -p value publish ports. e.g. "127.0.0.1:8080:80/tcp" - - Process: - --pidns create a PID namespace (default: false) - --cgroupns create a cgroup namespace (default: false) - --utsns create a UTS namespace (default: false) - --ipcns create an IPC namespace (default: false) - --reaper value enable process reaper. Requires --pidns. [auto,true,false] (default: "auto") - --evacuate-cgroup2 value evacuate processes into the specified subgroup. Requires --pidns and --cgroupns - - State: - --state-dir value state directory - + Misc: + --debug debug mode (default: false) + --help, -h show help (default: false) + --version, -v print the version (default: false) + + Mount: + --copy-up value [ --copy-up value ] mount a filesystem and copy-up the contents. e.g. "--copy-up=/etc" (typically required for non-host network) + --copy-up-mode value copy-up mode [tmpfs+symlink] + --propagation value mount propagation [rprivate, rslave] + + Network: + --net value network driver [host, slirp4netns, vpnkit, lxc-user-nic(experimental)] + --mtu value MTU for non-host network (default: 65520 for slirp4netns, 1500 for others) (default: 0) + --cidr value CIDR for slirp4netns network (default: 10.0.2.0/24) + --ifname value Network interface name (default: tap0 for slirp4netns and vpnkit, eth0 for lxc-user-nic) + --disable-host-loopback prohibit connecting to 127.0.0.1:* on the host namespace (default: false) + --ipv6 enable IPv6 routing. Unrelated to port forwarding. Only supported for slirp4netns. (experimental) (default: false) + + Network [lxc-user-nic]: + --lxc-user-nic-binary value path of lxc-user-nic binary for --net=lxc-user-nic + --lxc-user-nic-bridge value lxc-user-nic bridge name + + Network [slirp4netns]: + --slirp4netns-binary value path of slirp4netns binary for --net=slirp4netns + --slirp4netns-sandbox value enable slirp4netns sandbox (experimental) [auto, true, false] (the default is planned to be "auto" in future) + --slirp4netns-seccomp value enable slirp4netns seccomp (experimental) [auto, true, false] (the default is planned to be "auto" in future) + + Network [vpnkit]: + --vpnkit-binary value path of VPNKit binary for --net=vpnkit + + Port: + --port-driver value port driver for non-host network. [none, builtin, slirp4netns] + --publish value, -p value [ --publish value, -p value ] publish ports. e.g. "127.0.0.1:8080:80/tcp" + + Process: + --pidns create a PID namespace (default: false) + --cgroupns create a cgroup namespace (default: false) + --utsns create a UTS namespace (default: false) + --ipcns create an IPC namespace (default: false) + --reaper value enable process reaper. Requires --pidns. [auto,true,false] + --evacuate-cgroup2 value evacuate processes into the specified subgroup. Requires --pidns and --cgroupns + + State: + --state-dir value state directory + + SubID: + --subid-source value the source of the subids. "dynamic" executes /usr/bin/getsubids. "static" reads /etc/{subuid,subgid}. [auto,dynamic,static] + ``` ## State directory @@ -249,3 +254,4 @@ - [`./docs/mount.md`](./docs/mount.md): Mount (`--propagation`, ...) - [`./docs/process.md`](./docs/process.md): Process (`--pidns`, `--reaper`, `--cgroupns`, `--evacuate-cgroup2`, ...) - [`./docs/api.md`](./docs/api.md): REST API +- [`./docs/subid.md`](./docs/subid.md): Sub UIDs and sub GIDs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/cmd/rootlesskit/category.go new/rootlesskit-1.1.0/cmd/rootlesskit/category.go --- old/rootlesskit-1.0.0/cmd/rootlesskit/category.go 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/cmd/rootlesskit/category.go 2022-11-15 12:09:45.000000000 +0100 @@ -16,6 +16,7 @@ CategoryPort = "Port" CategoryMount = "Mount" CategoryProcess = "Process" + CategorySubID = "SubID" CategoryMisc = "Misc" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/cmd/rootlesskit/main.go new/rootlesskit-1.1.0/cmd/rootlesskit/main.go --- old/rootlesskit-1.0.0/cmd/rootlesskit/main.go 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/cmd/rootlesskit/main.go 2022-11-15 12:09:45.000000000 +0100 @@ -176,6 +176,11 @@ Name: "evacuate-cgroup2", Usage: "evacuate processes into the specified subgroup. Requires --pidns and --cgroupns", }, CategoryProcess), + Categorize(&cli.StringFlag{ + Name: "subid-source", + Value: "auto", + Usage: "the source of the subids. \"dynamic\" executes /usr/bin/getsubids. \"static\" reads /etc/{subuid,subgid}. [auto,dynamic,static]", + }, CategorySubID), } app.CustomAppHelpTemplate = `NAME: {{.Name}}{{if .Usage}} - {{.Usage}}{{end}} @@ -264,6 +269,7 @@ ParentEGIDEnvKey: parentEGIDEnvKey, Propagation: clicontext.String("propagation"), EvacuateCgroup2: clicontext.String("evacuate-cgroup2"), + SubidSource: parent.SubidSource(clicontext.String("subid-source")), } if opt.EvacuateCgroup2 != "" { if !opt.CreateCgroupNS { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/docs/subid.md new/rootlesskit-1.1.0/docs/subid.md --- old/rootlesskit-1.0.0/docs/subid.md 1970-01-01 01:00:00.000000000 +0100 +++ new/rootlesskit-1.1.0/docs/subid.md 2022-11-15 12:09:45.000000000 +0100 @@ -0,0 +1,40 @@ +# subid sources + +The subid sources can be specified via the `--subid-source=(auto|dynamic|static)` flag. + +The `auto` source is the default since RootlessKit v1.1.0. +Prior to v1.1.0, only the `static` source was supported. + +## Auto +The `auto` source (`--subid-source=auto`) tries the `dynamic` source and fall backs to the `static` source on an error. + +## Dynamic +The `dynamic` source (`--subid-source=dynamic`) executes the `/usr/bin/getsubids` binary to get the subids. + +The `getsubuids` binary is known to be available for the following distributions: +- Fedora, since 35 (`dnf install shadow-utils-subid`) +- Alpine, since 3.16 (`apkg install shadow-subids`) +- Ubuntu, since 22.10 (`apt-get install uidmap`) + +The `getsubids` binary typically reads subids from `/etc/subuid` and `/etc/subgid` as in the static mode, +but it can be also configured to use SSSD by specifying `subid: sss` in `/etc/nsswitch.conf`. + +See also https://manpages.debian.org/testing/uidmap/getsubids.1.en.html . + +## Static +The `static` source (`--subid-source=static`) reads subids from `/etc/subuid` and `/etc/subgid`. + +`/etc/subuid` and `/etc/subgid` should contain more than 65536 sub-IDs. e.g. `penguin:231072:65536`. These files are automatically configured on most distributions. + +```console +$ id -u +1001 +$ whoami +penguin +$ grep "^$(whoami):" /etc/subuid +penguin:231072:65536 +$ grep "^$(whoami):" /etc/subgid +penguin:231072:65536 +``` + +See also https://rootlesscontaine.rs/getting-started/common/subuid/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/go.mod new/rootlesskit-1.1.0/go.mod --- old/rootlesskit-1.0.0/go.mod 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/go.mod 2022-11-15 12:09:45.000000000 +0100 @@ -1,17 +1,26 @@ module github.com/rootless-containers/rootlesskit -go 1.16 +go 1.19 require ( github.com/gofrs/flock v0.8.1 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 github.com/insomniacslk/dhcp v0.0.0-20220119180841-3c283ff8b7dd - github.com/moby/sys/mountinfo v0.6.0 + github.com/moby/sys/mountinfo v0.6.2 github.com/moby/vpnkit v0.5.0 - github.com/sirupsen/logrus v1.8.1 + github.com/sirupsen/logrus v1.9.0 github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 - github.com/stretchr/testify v1.7.1 - github.com/urfave/cli/v2 v2.4.0 - golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 + github.com/urfave/cli/v2 v2.23.5 + golang.org/x/sys v0.2.0 + gotest.tools/v3 v3.4.0 +) + +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/google/go-cmp v0.5.5 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + golang.org/x/net v0.1.0 // indirect ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/go.sum new/rootlesskit-1.1.0/go.sum --- old/rootlesskit-1.0.0/go.sum 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/go.sum 2022-11-15 12:09:45.000000000 +0100 @@ -1,6 +1,5 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -12,6 +11,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -32,41 +33,50 @@ github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o= github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= -github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo= -github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= +github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/vpnkit v0.5.0 h1:VcDpS9y+PmT9itf+mH5Qdh9GME7ungLMt9yjf9o4REY= github.com/moby/vpnkit v0.5.0/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8= github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/u-root/uio v0.0.0-20210528114334-82958018845c h1:BFvcl34IGnw8yvJi8hlqLFo9EshRInwWBs2M5fGWzQA= github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA= -github.com/urfave/cli/v2 v2.4.0 h1:m2pxjjDFgDxSPtO8WSdbndj17Wu2y8vOT86wE/tjr+I= -github.com/urfave/cli/v2 v2.4.0/go.mod h1:NX9W0zmTvedE5oDoOMs2RTC8RvdK98NTYZE5LbaEYPg= +github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw= +github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -75,22 +85,30 @@ golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/hack/make-cross.sh new/rootlesskit-1.1.0/hack/make-cross.sh --- old/rootlesskit-1.0.0/hack/make-cross.sh 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/hack/make-cross.sh 2022-11-15 12:09:45.000000000 +0100 @@ -21,6 +21,7 @@ x arm64 aarch64 x s390x s390x x ppc64le ppc64le +x riscv64 riscv64 GOARM=7 export GOARM x arm armv7l diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/pkg/network/slirp4netns/slirp4netns.go new/rootlesskit-1.1.0/pkg/network/slirp4netns/slirp4netns.go --- old/rootlesskit-1.0.0/pkg/network/slirp4netns/slirp4netns.go 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/pkg/network/slirp4netns/slirp4netns.go 2022-11-15 12:09:45.000000000 +0100 @@ -103,7 +103,7 @@ return nil, err } if enableIPv6 && !features.SupportsEnableIPv6 { - return nil, errors.New("this version of slirp4netns does not support --enable-sandbox") + return nil, errors.New("this version of slirp4netns does not support --enable-ipv6") } if ipnet != nil && !features.SupportsCIDR { return nil, errors.New("this version of slirp4netns does not support --cidr") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/pkg/parent/dynidtools/dynidtools.go new/rootlesskit-1.1.0/pkg/parent/dynidtools/dynidtools.go --- old/rootlesskit-1.0.0/pkg/parent/dynidtools/dynidtools.go 1970-01-01 01:00:00.000000000 +0100 +++ new/rootlesskit-1.1.0/pkg/parent/dynidtools/dynidtools.go 2022-11-15 12:09:45.000000000 +0100 @@ -0,0 +1,122 @@ +package dynidtools + +import ( + "bufio" + "bytes" + "fmt" + "io" + "os" + "os/exec" + "strconv" + "strings" + + "github.com/rootless-containers/rootlesskit/pkg/parent/idtools" + "github.com/sirupsen/logrus" +) + +func GetSubIDRanges(uid int, username string) ([]idtools.SubIDRange, []idtools.SubIDRange, error) { + getsubidsExeName := "getsubids" + if v := os.Getenv("GETSUBIDS"); v != "" { + getsubidsExeName = v + } + getsubidsExe, err := exec.LookPath(getsubidsExeName) + if err != nil { + return nil, nil, fmt.Errorf("subid-source:dynamic: %w", err) + } + + uByUsername, uByUsernameErr := execGetsubids(getsubidsExe, false, username) + uByUID, uByUIDErr := execGetsubids(getsubidsExe, false, strconv.Itoa(uid)) + // Typically, uByUsernameErr == nil, uByUIDErr == "Error fetching ranges" (exit code 1) + if uByUsernameErr != nil { + logrus.WithError(uByUsernameErr).Debugf("subid-source:dynamic: failed to get subuids by the username %q", username) + } + if uByUIDErr != nil { + logrus.WithError(uByUIDErr).Debugf("subid-source:dynamic: failed to get subuids by the UID %d", uid) + if uByUsernameErr != nil { + return nil, nil, fmt.Errorf("subid-source:dynamic: failed to get subuids by the username %q: %w; also failed to get subuids by the UID %d: %v", + username, uByUsernameErr, uid, uByUIDErr) + } + } + + gByUsername, gByUsernameErr := execGetsubids(getsubidsExe, true, username) + gByUID, gByUIDErr := execGetsubids(getsubidsExe, true, strconv.Itoa(uid)) + // Typically, gByUsernameErr == nil, gByUIDErr == "Error fetching ranges" (exit code 1) + if gByUsernameErr != nil { + logrus.WithError(gByUsernameErr).Debugf("subid-source:dynamic: failed to get subgids by the username %q", username) + } + if gByUIDErr != nil { + logrus.WithError(gByUIDErr).Debugf("subid-source:dynamic: failed to get subgids by the UID %d", uid) + if gByUsernameErr != nil { + return nil, nil, fmt.Errorf("subid-source:dynamic: failed to get subgids by the username %q: %w; also failed to get subuids by the UID %d: %v", + username, gByUsernameErr, uid, gByUIDErr) + } + } + + u := append(uByUsername, uByUID...) + g := append(gByUsername, gByUID...) + return u, g, nil +} + +// execGetsubids executes `getsubids [-g] user` +func execGetsubids(exe string, g bool, s string) ([]idtools.SubIDRange, error) { + var args []string + if g { + args = append(args, "-g") + } + var stderr bytes.Buffer + args = append(args, s) + cmd := exec.Command(exe, args...) + cmd.Stderr = &stderr + logrus.Debugf("Executing %v", cmd.Args) + out, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("failed to exec %v: %w (stdout=%q, stderr=%q)", cmd.Args, err, string(out), stderr.String()) + } + r := bytes.NewReader(out) + ranges, warns, err := parseGetsubidsOutput(r) + for _, warn := range warns { + logrus.Warnf("Error while parsing the result of %v: %s (stdout=%q, stderr=%q)", cmd.Args, warn, string(out), stderr.String()) + } + return ranges, err +} + +func parseGetsubidsOutput(r io.Reader) (res []idtools.SubIDRange, warns []string, err error) { + sc := bufio.NewScanner(r) + for i := 0; sc.Scan(); i++ { + line := strings.TrimSpace(sc.Text()) + // line is like "0: foo 100000 655360" + if line == "" || strings.HasPrefix(line, "#") { + continue + } + splitByColon := strings.Split(line, ":") + switch len(splitByColon) { + case 0, 1: + return res, warns, fmt.Errorf("line %d: unparsable line %q", i+1, line) + case 2: + // NOP + default: + warns = append(warns, fmt.Sprintf("line %d: line %q contains unknown fields", i+1, line)) + } + triplet := strings.Fields(strings.TrimSpace(splitByColon[1])) + switch len(triplet) { + case 0, 1, 2: + return res, warns, fmt.Errorf("line %d: unparsable line %q", i+1, line) + case 3: + // NOP + default: + warns = append(warns, fmt.Sprintf("line %d: line %q contains unknown fields", i+1, line)) + } + var entry idtools.SubIDRange + entry.Start, err = strconv.Atoi(triplet[1]) + if err != nil { + return res, warns, fmt.Errorf("line %d: unparsable line %q: failed to Atoi(%q): %w", i+1, line, triplet[1], err) + } + entry.Length, err = strconv.Atoi(triplet[2]) + if err != nil { + return res, warns, fmt.Errorf("line %d: unparsable line %q: failed to Atoi(%q): %w", i+1, line, triplet[2], err) + } + res = append(res, entry) + } + err = sc.Err() + return +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/pkg/parent/dynidtools/dynidtools_test.go new/rootlesskit-1.1.0/pkg/parent/dynidtools/dynidtools_test.go --- old/rootlesskit-1.0.0/pkg/parent/dynidtools/dynidtools_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/rootlesskit-1.1.0/pkg/parent/dynidtools/dynidtools_test.go 2022-11-15 12:09:45.000000000 +0100 @@ -0,0 +1,25 @@ +package dynidtools + +import ( + "strings" + "testing" + + "github.com/rootless-containers/rootlesskit/pkg/parent/idtools" + "gotest.tools/v3/assert" +) + +func TestParseGetsubidsOutput(t *testing.T) { + const s = `# foo +0: foo 100000 655360 +` + expected := []idtools.SubIDRange{ + { + Start: 100000, + Length: 655360, + }, + } + got, warn, err := parseGetsubidsOutput(strings.NewReader(s)) + assert.NilError(t, err) + assert.Equal(t, 0, len(warn)) + assert.DeepEqual(t, expected, got) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/pkg/parent/idtools/idtools.go new/rootlesskit-1.1.0/pkg/parent/idtools/idtools.go --- old/rootlesskit-1.0.0/pkg/parent/idtools/idtools.go 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/pkg/parent/idtools/idtools.go 2022-11-15 12:09:45.000000000 +0100 @@ -9,203 +9,47 @@ "strings" ) -// IDMap contains a single entry for user namespace range remapping. An array -// of IDMap entries represents the structure that will be provided to the Linux -// kernel for creating a user namespace. -type IDMap struct { - ContainerID int `json:"container_id"` - HostID int `json:"host_id"` - Size int `json:"size"` -} - -type subIDRange struct { +type SubIDRange struct { Start int Length int } -type ranges []subIDRange - -func (e ranges) Len() int { return len(e) } -func (e ranges) Swap(i, j int) { e[i], e[j] = e[j], e[i] } -func (e ranges) Less(i, j int) bool { return e[i].Start < e[j].Start } - const ( subuidFileName = "/etc/subuid" subgidFileName = "/etc/subgid" ) -// GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps. -// If the maps are empty, then the root uid/gid will default to "real" 0/0 -func GetRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) { - uid, err := toHost(0, uidMap) - if err != nil { - return -1, -1, err - } - gid, err := toHost(0, gidMap) - if err != nil { - return -1, -1, err - } - return uid, gid, nil -} - -// toContainer takes an id mapping, and uses it to translate a -// host ID to the remapped ID. If no map is provided, then the translation -// assumes a 1-to-1 mapping and returns the passed in id -func toContainer(hostID int, idMap []IDMap) (int, error) { - if idMap == nil { - return hostID, nil - } - for _, m := range idMap { - if (hostID >= m.HostID) && (hostID <= (m.HostID + m.Size - 1)) { - contID := m.ContainerID + (hostID - m.HostID) - return contID, nil - } - } - return -1, fmt.Errorf("Host ID %d cannot be mapped to a container ID", hostID) -} - -// toHost takes an id mapping and a remapped ID, and translates the -// ID to the mapped host ID. If no map is provided, then the translation -// assumes a 1-to-1 mapping and returns the passed in id # -func toHost(contID int, idMap []IDMap) (int, error) { - if idMap == nil { - return contID, nil - } - for _, m := range idMap { - if (contID >= m.ContainerID) && (contID <= (m.ContainerID + m.Size - 1)) { - hostID := m.HostID + (contID - m.ContainerID) - return hostID, nil - } - } - return -1, fmt.Errorf("Container ID %d cannot be mapped to a host ID", contID) -} - -// Identity is either a UID and GID pair or a SID (but not both) -type Identity struct { - UID int - GID int - SID string -} - -// IdentityMapping contains a mappings of UIDs and GIDs -type IdentityMapping struct { - uids []IDMap - gids []IDMap -} - -// NewIdentityMapping takes a requested user and group name and -// using the data from /etc/sub{uid,gid} ranges, creates the -// proper uid and gid remapping ranges for that user/group pair -func NewIdentityMapping(uid int, username string) (*IdentityMapping, error) { +func GetSubIDRanges(uid int, username string) ([]SubIDRange, []SubIDRange, error) { subuidRanges, err := parseSubuid(uid, username) if err != nil { - return nil, err + return nil, nil, err } subgidRanges, err := parseSubgid(uid, username) if err != nil { - return nil, err + return nil, nil, err } if len(subuidRanges) == 0 { - return nil, fmt.Errorf("No subuid ranges found for user %d (%q)", uid, username) + return nil, nil, fmt.Errorf("No subuid ranges found for user %d (%q)", uid, username) } if len(subgidRanges) == 0 { - return nil, fmt.Errorf("No subgid ranges found for user %d (%q)", uid, username) - } - - return &IdentityMapping{ - uids: createIDMap(subuidRanges), - gids: createIDMap(subgidRanges), - }, nil -} - -// NewIDMappingsFromMaps creates a new mapping from two slices -// Deprecated: this is a temporary shim while transitioning to IDMapping -func NewIDMappingsFromMaps(uids []IDMap, gids []IDMap) *IdentityMapping { - return &IdentityMapping{uids: uids, gids: gids} -} - -// RootPair returns a uid and gid pair for the root user. The error is ignored -// because a root user always exists, and the defaults are correct when the uid -// and gid maps are empty. -func (i *IdentityMapping) RootPair() Identity { - uid, gid, _ := GetRootUIDGID(i.uids, i.gids) - return Identity{UID: uid, GID: gid} -} - -// ToHost returns the host UID and GID for the container uid, gid. -// Remapping is only performed if the ids aren't already the remapped root ids -func (i *IdentityMapping) ToHost(pair Identity) (Identity, error) { - var err error - target := i.RootPair() - - if pair.UID != target.UID { - target.UID, err = toHost(pair.UID, i.uids) - if err != nil { - return target, err - } - } - - if pair.GID != target.GID { - target.GID, err = toHost(pair.GID, i.gids) - } - return target, err -} - -// ToContainer returns the container UID and GID for the host uid and gid -func (i *IdentityMapping) ToContainer(pair Identity) (int, int, error) { - uid, err := toContainer(pair.UID, i.uids) - if err != nil { - return -1, -1, err - } - gid, err := toContainer(pair.GID, i.gids) - return uid, gid, err -} - -// Empty returns true if there are no id mappings -func (i *IdentityMapping) Empty() bool { - return len(i.uids) == 0 && len(i.gids) == 0 -} - -// UIDs return the UID mapping -// TODO: remove this once everything has been refactored to use pairs -func (i *IdentityMapping) UIDs() []IDMap { - return i.uids -} - -// GIDs return the UID mapping -// TODO: remove this once everything has been refactored to use pairs -func (i *IdentityMapping) GIDs() []IDMap { - return i.gids -} - -func createIDMap(subidRanges ranges) []IDMap { - idMap := []IDMap{} - - containerID := 0 - for _, idrange := range subidRanges { - idMap = append(idMap, IDMap{ - ContainerID: containerID, - HostID: idrange.Start, - Size: idrange.Length, - }) - containerID = containerID + idrange.Length + return nil, nil, fmt.Errorf("No subgid ranges found for user %d (%q)", uid, username) } - return idMap + return subuidRanges, subgidRanges, nil } -func parseSubuid(uid int, username string) (ranges, error) { +func parseSubuid(uid int, username string) ([]SubIDRange, error) { return parseSubidFile(subuidFileName, uid, username) } -func parseSubgid(uid int, username string) (ranges, error) { +func parseSubgid(uid int, username string) ([]SubIDRange, error) { return parseSubidFile(subgidFileName, uid, username) } // parseSubidFile will read the appropriate file (/etc/subuid or /etc/subgid) // and return all found ranges for a specified user. username is optional. -func parseSubidFile(path string, uid int, username string) (ranges, error) { +func parseSubidFile(path string, uid int, username string) ([]SubIDRange, error) { uidS := strconv.Itoa(uid) - var rangeList ranges + var rangeList []SubIDRange subidFile, err := os.Open(path) if err != nil { @@ -232,7 +76,7 @@ if err != nil { return rangeList, fmt.Errorf("String to int conversion failed during subuid/gid parsing of %s: %v", path, err) } - rangeList = append(rangeList, subIDRange{startid, length}) + rangeList = append(rangeList, SubIDRange{startid, length}) } } return rangeList, s.Err() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/pkg/parent/parent.go new/rootlesskit-1.1.0/pkg/parent/parent.go --- old/rootlesskit-1.0.0/pkg/parent/parent.go 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/pkg/parent/parent.go 2022-11-15 12:09:45.000000000 +0100 @@ -24,6 +24,7 @@ "github.com/rootless-containers/rootlesskit/pkg/msgutil" "github.com/rootless-containers/rootlesskit/pkg/network" "github.com/rootless-containers/rootlesskit/pkg/parent/cgrouputil" + "github.com/rootless-containers/rootlesskit/pkg/parent/dynidtools" "github.com/rootless-containers/rootlesskit/pkg/parent/idtools" "github.com/rootless-containers/rootlesskit/pkg/port" "github.com/rootless-containers/rootlesskit/pkg/sigproxy" @@ -45,8 +46,17 @@ ParentEGIDEnvKey string // optional env key to propagate getegid() value Propagation string EvacuateCgroup2 string // e.g. "rootlesskit_evacuation" + SubidSource SubidSource } +type SubidSource string + +const ( + SubidSourceAuto = SubidSource("auto") // Try dynamic then fallback to static + SubidSourceDynamic = SubidSource("dynamic") // /usr/bin/getsubids + SubidSourceStatic = SubidSource("static") // /etc/{subuid,subgid} +) + // Documented state files. Undocumented ones are subject to change. const ( StateFileLock = "lock" @@ -175,7 +185,7 @@ if err := cmd.Start(); err != nil { return fmt.Errorf("failed to start the child: %w", err) } - if err := setupUIDGIDMap(cmd.Process.Pid); err != nil { + if err := setupUIDGIDMap(cmd.Process.Pid, opt.SubidSource); err != nil { return fmt.Errorf("failed to setup UID/GID map: %w", err) } sigc := sigproxy.ForwardAllSignals(context.TODO(), cmd.Process.Pid) @@ -286,11 +296,45 @@ return err } -func newugidmapArgs() ([]string, []string, error) { +func getSubIDRanges(u *user.User, subidSource SubidSource) ([]idtools.SubIDRange, []idtools.SubIDRange, error) { + uid, err := strconv.Atoi(u.Uid) + if err != nil { + return nil, nil, err + } + switch subidSource { + case SubidSourceStatic: + logrus.Debugf("subid-source: using the static source") + return idtools.GetSubIDRanges(uid, u.Username) + case SubidSourceDynamic: + logrus.Debugf("subid-source: using the dynamic source") + return dynidtools.GetSubIDRanges(uid, u.Username) + case "", SubidSourceAuto: + subuidRanges, subgidRanges, err := getSubIDRanges(u, SubidSourceDynamic) + if err == nil && len(subuidRanges) > 0 && len(subgidRanges) > 0 { + return subuidRanges, subgidRanges, nil + } + logrus.WithError(err).Debugf("failed to use subid source %q, falling back to %q", SubidSourceDynamic, SubidSourceStatic) + return getSubIDRanges(u, SubidSourceStatic) + default: + return nil, nil, fmt.Errorf("unknown subid source %q", subidSource) + } +} + +func newugidmapArgs(subidSource SubidSource) ([]string, []string, error) { u, err := user.Current() if err != nil { return nil, nil, err } + subuidRanges, subgidRanges, err := getSubIDRanges(u, subidSource) + if err != nil { + return nil, nil, err + } + logrus.Debugf("subuid ranges=%v", subuidRanges) + logrus.Debugf("subgid ranges=%v", subgidRanges) + return newugidmapArgsFromSubIDRanges(u, subuidRanges, subgidRanges) +} + +func newugidmapArgsFromSubIDRanges(u *user.User, subuidRanges, subgidRanges []idtools.SubIDRange) ([]string, []string, error) { uidMap := []string{ "0", u.Uid, @@ -302,39 +346,30 @@ "1", } - uid, err := strconv.Atoi(u.Uid) - if err != nil { - return nil, nil, err - } - ims, err := idtools.NewIdentityMapping(uid, u.Username) - if err != nil { - return nil, nil, err - } - uidMapLast := 1 - for _, im := range ims.UIDs() { + for _, f := range subuidRanges { uidMap = append(uidMap, []string{ strconv.Itoa(uidMapLast), - strconv.Itoa(im.HostID), - strconv.Itoa(im.Size), + strconv.Itoa(f.Start), + strconv.Itoa(f.Length), }...) - uidMapLast += im.Size + uidMapLast += f.Length } gidMapLast := 1 - for _, im := range ims.GIDs() { + for _, f := range subgidRanges { gidMap = append(gidMap, []string{ strconv.Itoa(gidMapLast), - strconv.Itoa(im.HostID), - strconv.Itoa(im.Size), + strconv.Itoa(f.Start), + strconv.Itoa(f.Length), }...) - gidMapLast += im.Size + gidMapLast += f.Length } return uidMap, gidMap, nil } -func setupUIDGIDMap(pid int) error { - uArgs, gArgs, err := newugidmapArgs() +func setupUIDGIDMap(pid int, subidSource SubidSource) error { + uArgs, gArgs, err := newugidmapArgs(subidSource) if err != nil { return fmt.Errorf("failed to compute uid/gid map: %w", err) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/pkg/parent/parent_test.go new/rootlesskit-1.1.0/pkg/parent/parent_test.go --- old/rootlesskit-1.0.0/pkg/parent/parent_test.go 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/pkg/parent/parent_test.go 2022-11-15 12:09:45.000000000 +0100 @@ -2,9 +2,12 @@ import ( "os" + "os/user" "testing" + "github.com/rootless-containers/rootlesskit/pkg/parent/idtools" "golang.org/x/sys/unix" + "gotest.tools/v3/assert" ) func TestBSDLockFileCreated(t *testing.T) { @@ -25,3 +28,26 @@ t.Fatal("expected that there was an error because of existing LOCK_SH") } } + +func TestNewugidmapArgsFromSubIDRanges(t *testing.T) { + subuidRanges := []idtools.SubIDRange{ + {Start: 100000, Length: 65536}, + {Start: 200000, Length: 65536}, + } + subgidRanges := []idtools.SubIDRange{ + {Start: 100000, Length: 65536}, + {Start: 200000, Length: 65536}, + } + u, err := user.Current() + assert.NilError(t, err) + newuidmapArgs, newgidmapArgs, err := newugidmapArgsFromSubIDRanges(u, subuidRanges, subgidRanges) + assert.NilError(t, err) + expectedU := []string{ + "0", u.Uid, "1", "1", "100000", "65536", "65537", "200000", "65536", + } + expectedG := []string{ + "0", u.Gid, "1", "1", "100000", "65536", "65537", "200000", "65536", + } + assert.DeepEqual(t, expectedU, newuidmapArgs) + assert.DeepEqual(t, expectedG, newgidmapArgs) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/pkg/port/portutil/portutil_test.go new/rootlesskit-1.1.0/pkg/port/portutil/portutil_test.go --- old/rootlesskit-1.0.0/pkg/port/portutil/portutil_test.go 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/pkg/port/portutil/portutil_test.go 2022-11-15 12:09:45.000000000 +0100 @@ -5,7 +5,7 @@ "testing" "github.com/rootless-containers/rootlesskit/pkg/port" - "github.com/stretchr/testify/assert" + "gotest.tools/v3/assert" ) func TestParsePortSpec(t *testing.T) { @@ -132,21 +132,21 @@ s := spec s.Proto = p err := ValidatePortSpec(s, existingPorts) - assert.Error(t, err) + assert.ErrorContains(t, err, "unknown proto") } for _, p := range validProtos { s := spec s.Proto = p err := ValidatePortSpec(s, existingPorts) - assert.NoError(t, err) + assert.NilError(t, err) } s := port.Spec{Proto: "tcp", ParentIP: "invalid", ParentPort: 80, ChildPort: 80} - assert.Error(t, ValidatePortSpec(s, existingPorts)) + assert.ErrorContains(t, ValidatePortSpec(s, existingPorts), "invalid ParentIP") s = port.Spec{Proto: "tcp", ParentPort: 80, ChildIP: "invalid", ChildPort: 80} - assert.Error(t, ValidatePortSpec(s, existingPorts)) + assert.ErrorContains(t, ValidatePortSpec(s, existingPorts), "invalid ChildIP") invalidPorts := []int{-200, 0, 1000000} validPorts := []int{20, 500, 1337, 65000} @@ -156,13 +156,13 @@ s := spec s.ParentPort = p err := ValidatePortSpec(s, existingPorts) - assert.Error(t, err) + assert.ErrorContains(t, err, "invalid ParentPort") } for _, p := range validPorts { s := spec s.ParentPort = p err := ValidatePortSpec(s, existingPorts) - assert.NoError(t, err) + assert.NilError(t, err) } // 0 < childPort <= 65535 @@ -170,13 +170,13 @@ s := spec s.ChildPort = p err := ValidatePortSpec(s, existingPorts) - assert.Error(t, err, "invalid ChildPort") + assert.ErrorContains(t, err, "invalid ChildPort") } for _, p := range validPorts { s := spec s.ChildPort = p err := ValidatePortSpec(s, existingPorts) - assert.NoError(t, err) + assert.NilError(t, err) } // ChildPorts can overlap so long as parent port/IPs don't @@ -184,24 +184,24 @@ // udp doesn't conflict with tcp s = port.Spec{Proto: "udp", ParentPort: 80, ChildPort: 80} - assert.NoError(t, ValidatePortSpec(s, existingPorts)) + assert.NilError(t, ValidatePortSpec(s, existingPorts)) // same parent, same child, different IP has no conflict s = port.Spec{Proto: "tcp", ParentIP: "10.10.10.11", ParentPort: 8080, ChildPort: 8080} - assert.NoError(t, ValidatePortSpec(s, existingPorts)) + assert.NilError(t, ValidatePortSpec(s, existingPorts)) // same IP different parentPort, same child port has no conflict s = port.Spec{Proto: "tcp", ParentIP: "10.10.10.10", ParentPort: 8081, ChildPort: 8080} - assert.NoError(t, ValidatePortSpec(s, existingPorts)) + assert.NilError(t, ValidatePortSpec(s, existingPorts)) // Same parent IP and Port should conflict, even if child port different // conflict with ID 1: s = port.Spec{Proto: "tcp", ParentPort: 80, ChildPort: 90} err := ValidatePortSpec(s, existingPorts) - assert.EqualError(t, err, "conflict with ID 1") + assert.Error(t, err, "conflict with ID 1") // conflict with ID 2 s = port.Spec{Proto: "tcp", ParentIP: "10.10.10.10", ParentPort: 8080, ChildPort: 8080} err = ValidatePortSpec(s, existingPorts) - assert.EqualError(t, err, "conflict with ID 2") + assert.Error(t, err, "conflict with ID 2") } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rootlesskit-1.0.0/pkg/version/version.go new/rootlesskit-1.1.0/pkg/version/version.go --- old/rootlesskit-1.0.0/pkg/version/version.go 2022-03-25 11:22:25.000000000 +0100 +++ new/rootlesskit-1.1.0/pkg/version/version.go 2022-11-15 12:09:45.000000000 +0100 @@ -1,3 +1,3 @@ package version -const Version = "1.0.0" +const Version = "1.1.0" ++++++ vendor.tar.gz ++++++ ++++ 87563 lines of diff (skipped)
