summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml39
-rw-r--r--Makefile7
-rw-r--r--contrib/cirrus/README.md20
-rw-r--r--contrib/cirrus/lib.sh53
-rwxr-xr-xcontrib/cirrus/rootless_test.sh36
-rwxr-xr-xcontrib/cirrus/setup_environment.sh20
-rw-r--r--crio-umount.conf8
-rw-r--r--libpod/runtime_pod_infra_linux.go24
-rw-r--r--test/README.md32
-rw-r--r--test/e2e/pod_infra_container_test.go12
-rw-r--r--troubleshooting.md39
11 files changed, 256 insertions, 34 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 328b2e676..9ce690196 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -67,6 +67,13 @@ env:
RHEL_BASE_IMAGE: "rhel-guest-image-7-6-210-x86-64-qcow2-1548099756"
####
+ #### Default to NOT running in rootless-testing mode
+ ####
+ ROOTLESS_USER:
+ ROOTLESS_UID:
+ ROOTLESS_GID:
+
+ ####
#### Credentials and other secret-sauces, decrypted at runtime when authorized.
####
# Freenode IRC credentials for posting status messages
@@ -94,7 +101,7 @@ env:
CIRRUS_TASK_ID CIRRUS_REPO_NAME CIRRUS_REPO_OWNER CIRRUS_REPO_FULL_NAME
CIRRUS_REPO_CLONE_URL CIRRUS_SHELL CIRRUS_USER_COLLABORATOR CIRRUS_USER_PERMISSION
CIRRUS_WORKING_DIR CIRRUS_HTTP_CACHE_HOST PACKER_BUILDS BUILT_IMAGE_SUFFIX
- XDG_DATA_DIRS XDG_RUNTIME_DIR XDG_SESSION_ID
+ XDG_DATA_DIRS XDG_RUNTIME_DIR XDG_SESSION_ID ROOTLESS_USER ROOTLESS_UID ROOTLESS_GID
# Every *_task runs in parallel in separate VMsd. The name prefix only for reference
@@ -220,6 +227,36 @@ testing_task:
integration_test_script: $SCRIPT_BASE/integration_test.sh
+# This task executes tests as a regular user on a system
+rootless_testing_task:
+
+ depends_on:
+ - "gating"
+ - "build_each_commit"
+
+ gce_instance:
+ image_project: "libpod-218412"
+ zone: "us-central1-a" # Required by Cirrus for the time being
+ cpu: 2
+ memory: "4Gb"
+ disk: 200
+ # A matrix could be used here, for now just one VM
+ image_name: "${FEDORA_CACHE_IMAGE_NAME}"
+
+ env:
+ ROOTLESS_USER: "olympiclongjumpingwithjesus"
+ ROOTLESS_UID: 123456
+ ROOTLESS_GID: 123456
+
+ timeout_in: 120m
+
+ setup_environment_script: $SCRIPT_BASE/setup_environment.sh
+ rootless_test_script: >-
+ ssh $ROOTLESS_USER@localhost
+ -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no
+ $CIRRUS_WORKING_DIR/$SCRIPT_BASE/rootless_test.sh
+
+
# Because system tests are stored within the repository, it is sometimes
# necessary to execute them within a PR to validate changes.
optional_testing_task:
diff --git a/Makefile b/Makefile
index 5e7ee78b5..b456b4acf 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,6 @@ LIBEXECDIR ?= ${PREFIX}/libexec
MANDIR ?= ${PREFIX}/share/man
SHAREDIR_CONTAINERS ?= ${PREFIX}/share/containers
ETCDIR ?= ${DESTDIR}/etc
-ETCDIR_LIBPOD ?= ${ETCDIR}/crio
TMPFILESDIR ?= ${PREFIX}/lib/tmpfiles.d
SYSTEMDDIR ?= ${PREFIX}/lib/systemd/system
BUILDTAGS ?= seccomp $(shell hack/btrfs_tag.sh) $(shell hack/btrfs_installed_tag.sh) $(shell hack/ostree_tag.sh) $(shell hack/selinux_tag.sh) $(shell hack/apparmor_tag.sh) varlink exclude_graphdriver_devicemapper
@@ -28,7 +27,6 @@ CONTAINER_RUNTIME := $(shell command -v podman 2> /dev/null || echo docker)
OCI_RUNTIME ?= ""
BASHINSTALLDIR=${PREFIX}/share/bash-completion/completions
-OCIUMOUNTINSTALLDIR=$(PREFIX)/share/oci-umount/oci-umount.d
SELINUXOPT ?= $(shell test -x /usr/sbin/selinuxenabled && selinuxenabled && echo -Z)
PACKAGES ?= $(shell $(GO) list -tags "${BUILDTAGS}" ./... | grep -v github.com/containers/libpod/vendor | grep -v e2e | grep -v system )
@@ -242,10 +240,9 @@ install.man: docs
install ${SELINUXOPT} -m 644 docs/links/*1 -t $(MANDIR)/man1
install.config:
- install ${SELINUXOPT} -d -m 755 $(SHAREDIR_CONTAINERS) $(ETCDIR_LIBPOD) $(OCIUMOUNTINSTALLDIR)
+ install ${SELINUXOPT} -d -m 755 $(SHAREDIR_CONTAINERS)
install ${SELINUXOPT} -m 644 libpod.conf $(SHAREDIR_CONTAINERS)/libpod.conf
- install ${SELINUXOPT} -m 644 seccomp.json $(ETCDIR_LIBPOD)/seccomp.json
- install ${SELINUXOPT} -m 644 crio-umount.conf $(OCIUMOUNTINSTALLDIR)/crio-umount.conf
+ install ${SELINUXOPT} -m 644 seccomp.json $(SHAREDIR_CONTAINERS)/seccomp.json
install.completions:
install ${SELINUXOPT} -d -m 755 ${BASHINSTALLDIR}
diff --git a/contrib/cirrus/README.md b/contrib/cirrus/README.md
index e3b3182ec..0dabf5df6 100644
--- a/contrib/cirrus/README.md
+++ b/contrib/cirrus/README.md
@@ -63,6 +63,26 @@ task (pass or fail) is set based on the exit status of the last script to execut
Total execution time is capped at 2-hours (includes all the above)
but this script normally completes in less than an hour.
+### ``rootless_testing`` Task
+
+***N/B: Steps below are performed by automation***
+
+1. After `gating` passes, spin up one VM per
+ `matrix: image_name` item. Once accessible, ``ssh``
+ into each VM as the `root` user.
+
+2. ``setup_environment.sh``: Configure root's `.bash_profile`
+ the same as for other tasks. However, also add a regular
+ user account, chown all the source code to them. Set up
+ fresh ssh pub/priv. keys for the root user, adding the
+ public part to the user's `authorized_keys` file.
+
+3. As root, call ssh to connect to localhost as the user,
+ and run the ``rootless_test.sh`` script from the source
+ tree. This is needed so the user has a clean process tree
+ and environment - i.e. without `sudo`, `su`, `runuser`,
+ etc. in the mix. From here, all testing as the user may
+ be performed.
### ``optional_testing`` Task
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh
index acd2447c0..9419dad05 100644
--- a/contrib/cirrus/lib.sh
+++ b/contrib/cirrus/lib.sh
@@ -53,6 +53,9 @@ show_env_vars() {
echo "
BUILDTAGS $BUILDTAGS
BUILT_IMAGE_SUFFIX $BUILT_IMAGE_SUFFIX
+ROOTLESS_USER $ROOTLESS_USER
+ROOTLESS_UID $ROOTLESS_UID
+ROOTLESS_GID $ROOTLESS_GID
CI $CI
CIRRUS_CI $CIRRUS_CI
CI_NODE_INDEX $CI_NODE_INDEX
@@ -117,6 +120,15 @@ bad_os_id_ver() {
exit 42
}
+run_rootless() {
+ if [[ -z "$ROOTLESS_USER" ]] && [[ -z "$ROOTLESS_UID" ]] && [[ -z "$ROOTLESS_GID" ]]
+ then
+ return 1
+ else
+ return 0
+ fi
+}
+
stub() {
echo "STUB: Pretending to do $1"
}
@@ -146,12 +158,41 @@ record_timestamp() {
echo -e "BLEEEEEEEEEEP!\n."
}
-# Run sudo in directory with GOPATH set
-cdsudo() {
- DIR="$1"
- shift
- CMD="cd $DIR && $@"
- sudo --preserve-env=GOPATH --non-interactive bash -c "$CMD"
+setup_rootless() {
+ req_env_var "
+ ROOTLESS_USER $ROOTLESS_USER
+ ROOTLESS_UID $ROOTLESS_UID
+ ROOTLESS_GID $ROOTLESS_GID
+ GOSRC $GOSRC
+ ENVLIB $ENVLIB
+ "
+ echo "creating $ROOTLESS_UID:$ROOTLESS_GID $ROOTLESS_USER user"
+ groupadd -g $ROOTLESS_GID $ROOTLESS_USER
+ useradd -g $ROOTLESS_GID -u $ROOTLESS_UID --no-user-group --create-home $ROOTLESS_USER
+ chown -R $ROOTLESS_UID:$ROOTLESS_GID "$GOSRC"
+
+ echo "creating ssh keypair for $USER"
+ ssh-keygen -P "" -f $HOME/.ssh/id_rsa
+
+ echo "Allowing ssh key for $ROOTLESS_USER"
+ (umask 077 && mkdir "/home/$ROOTLESS_USER/.ssh")
+ chown -R $ROOTLESS_UID:$ROOTLESS_GID "/home/$ROOTLESS_USER/.ssh"
+ install -o $ROOTLESS_UID -g $ROOTLESS_GID -m 0600 \
+ "$HOME/.ssh/id_rsa.pub" "/home/$ROOTLESS_USER/.ssh/authorized_keys"
+
+ echo "Setting permissions on automation files"
+ chmod 666 "$TIMESTAMPS_FILEPATH"
+
+ echo "Copying $HOME/$ENVLIB"
+ install -o $ROOTLESS_UID -g $ROOTLESS_GID -m 0700 \
+ "$HOME/$ENVLIB" "/home/$ROOTLESS_USER/$ENVLIB"
+
+ echo "Configuring user's go environment variables"
+ su --login --command 'go env' $ROOTLESS_USER | \
+ while read envline
+ do
+ X=$(echo "export $envline" | tee -a "/home/$ROOTLESS_USER/$ENVLIB") && echo "$X"
+ done
}
# Helper/wrapper script to only show stderr/stdout on non-zero exit
diff --git a/contrib/cirrus/rootless_test.sh b/contrib/cirrus/rootless_test.sh
new file mode 100755
index 000000000..811b7cf2e
--- /dev/null
+++ b/contrib/cirrus/rootless_test.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+set -e
+source $HOME/.bash_profile
+
+cd $GOSRC
+source $(dirname $0)/lib.sh
+
+req_env_var "
+GOSRC $GOSRC
+OS_RELEASE_ID $OS_RELEASE_ID
+OS_RELEASE_VER $OS_RELEASE_VER
+"
+
+if ! run_rootless
+then
+ echo "Error: Expected rootless env. vars not set or empty"
+ exit 1
+fi
+
+echo "."
+echo "Hello, my name is $USER and I live in $PWD can I be your friend?"
+
+record_timestamp "rootless test start"
+
+cd "$GOSRC"
+case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in
+ ubuntu-18) ;& # Continue to the next item
+ fedora-29) ;&
+ fedora-28)
+ make
+ ;;
+ *) bad_os_id_ver ;;
+esac
+
+record_timestamp "rootless test end"
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index c3276bb6f..d8d97904b 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -43,6 +43,9 @@ then
"export OS_RELEASE_ID=\"$(os_release_id)\"" \
"export OS_RELEASE_VER=\"$(os_release_ver)\"" \
"export OS_REL_VER=\"$(os_release_id)-$(os_release_ver)\"" \
+ "export ROOTLESS_USER=$ROOTLESS_USER" \
+ "export ROOTLESS_UID=$ROOTLESS_UID" \
+ "export ROOTLESS_GID=$ROOTLESS_GID" \
"export BUILT_IMAGE_SUFFIX=\"-$CIRRUS_REPO_NAME-${CIRRUS_CHANGE_IN_REPO:0:8}\"" \
"export GOPATH=\"/var/tmp/go\"" \
'export PATH="$HOME/bin:$GOPATH/bin:/usr/local/bin:$PATH"' \
@@ -70,14 +73,19 @@ then
*) bad_os_id_ver ;;
esac
- # Do the same for golang env. vars
- go env | while read envline
- do
- X=$(echo "export $envline" | tee -a "$HOME/$ENVLIB") && eval "$X" && echo "$X"
- done
-
cd "${GOSRC}/"
source "$SCRIPT_BASE/lib.sh"
+
+ if run_rootless
+ then
+ setup_rootless
+ else
+ # Includes some $HOME relative details
+ go env | while read envline
+ do
+ X=$(echo "export $envline" | tee -a "$HOME/$ENVLIB") && eval "$X" && echo "$X"
+ done
+ fi
fi
record_timestamp "env. setup end"
diff --git a/crio-umount.conf b/crio-umount.conf
deleted file mode 100644
index 5177e6362..000000000
--- a/crio-umount.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-# This contains a list of paths on host which will be unmounted inside
-# container. (If they are mounted inside container).
-
-# If there is a "/*" at the end, that means only mounts underneath that
-# mounts (submounts) will be unmounted but top level mount will remain
-# in place.
-/var/run/containers/*
-/var/lib/containers/storage/*
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index 4f221764a..81579db4b 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -4,11 +4,14 @@ package libpod
import (
"context"
+ "strings"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/rootless"
+ "github.com/opencontainers/image-spec/specs-go/v1"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
+ "github.com/pkg/errors"
)
const (
@@ -17,7 +20,7 @@ const (
IDTruncLength = 12
)
-func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID string) (*Container, error) {
+func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID string, config *v1.ImageConfig) (*Container, error) {
// Set up generator for infra container defaults
g, err := generate.New("linux")
@@ -27,8 +30,23 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID
isRootless := rootless.IsRootless()
+ entryCmd := []string{r.config.InfraCommand}
+ // default to entrypoint in image if there is one
+ if len(config.Entrypoint) > 0 {
+ entryCmd = config.Entrypoint
+ }
+ if len(config.Env) > 0 {
+ for _, nameValPair := range config.Env {
+ nameValSlice := strings.Split(nameValPair, "=")
+ if len(nameValSlice) < 2 {
+ return nil, errors.Errorf("Invalid environment variable structure in pause image")
+ }
+ g.AddProcessEnv(nameValSlice[0], nameValSlice[1])
+ }
+ }
+
g.SetRootReadonly(true)
- g.SetProcessArgs([]string{r.config.InfraCommand})
+ g.SetProcessArgs(entryCmd)
if isRootless {
g.RemoveMount("/dev/pts")
@@ -79,5 +97,5 @@ func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container,
imageName := newImage.Names()[0]
imageID := data.ID
- return r.makeInfraContainer(ctx, p, imageName, imageID)
+ return r.makeInfraContainer(ctx, p, imageName, imageID, newImage.Config)
}
diff --git a/test/README.md b/test/README.md
index 5e5a7da61..4e61a0774 100644
--- a/test/README.md
+++ b/test/README.md
@@ -43,6 +43,11 @@ Build ginkgo and install it under $GOPATH/bin with the following command:
```
GOPATH=~/go make .install.ginkgo
```
+If your PATH does not include $GOPATH/bin, you might consider adding it.
+
+```
+PATH=$PATH:$GOPATH/bin
+```
# Integration Tests
Test suite for integration test for podman command line. It has its own structs:
@@ -63,21 +68,38 @@ GOPATH=~/go ginkgo -v test/e2e/.
Note the trailing period on the command above. Also, **-v** invokes verbose mode. That
switch is optional.
+
+### Running a single file of integration tests
You can run a single file of integration tests using the go test command:
```
GOPATH=~/go go test -v test/e2e/libpod_suite_test.go test/e2e/common_test.go test/e2e/config.go test/e2e/config_amd64.go test/e2e/your_test.go
```
-#### Run all tests like PAPR
-You can closely emulate the PAPR run for Fedora with the following command:
+### Running a single integration test
+Before running the test suite, you have to declare which test you want run in the test
+file itself. Consider the following actual test:
+```
+It("podman inspect bogus pod", func() {
+ session := podmanTest.Podman([]string{"pod", "inspect", "foobar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+ })
+```
+
+To mark this as the test you want run, you simply change the *It* description to *FIt*. Please note how
+both the `F` and `I` are capitalized.
+
+You can run a single integration test using the same command we used to run all the tests in a single
+file.
```
-make integration.fedora
+GOPATH=~/go go test -v test/e2e/libpod_suite_test.go test/e2e/common_test.go test/e2e/config.go test/e2e/config_amd64.go test/e2e/your_test.go
```
-This will run lint, git-validation, and gofmt tests and then execute unit and integration
-tests as well.
+*Note*: Be sure you remove the `F` from the tests before committing your changes or you will skip all tests
+in that file except the one with the `FIt` denotation.
+
### Run tests in a container
In case you have issue running the tests locally on your machine, you can run
diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go
index 99197dc39..82f35999c 100644
--- a/test/e2e/pod_infra_container_test.go
+++ b/test/e2e/pod_infra_container_test.go
@@ -69,6 +69,18 @@ var _ = Describe("Podman pod create", func() {
Expect(len(check.OutputToStringArray())).To(Equal(1))
})
+ It("podman start infra container different image", func() {
+ session := podmanTest.Podman([]string{"pod", "create", "--infra-image", BB})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ podID := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"pod", "start", podID})
+ session.WaitWithDefaultTimeout()
+ // If we use the default entry point, we should exit with no error
+ Expect(session.ExitCode()).To(Equal(0))
+ })
+
It("podman infra container namespaces", func() {
session := podmanTest.Podman([]string{"pod", "create"})
session.WaitWithDefaultTimeout()
diff --git a/troubleshooting.md b/troubleshooting.md
index 24a1dc6cb..33434cdbb 100644
--- a/troubleshooting.md
+++ b/troubleshooting.md
@@ -254,3 +254,42 @@ grep johndoe /etc/subuid /etc/subgid
/etc/subuid:johndoe:200000:1001
/etc/subgid:johndoe:200000:1001
```
+
+### 11) Changing the location of the Graphroot leads to permission denied
+
+When I change the graphroot storage location in storage.conf, the next time I
+run podman I get an error like:
+
+```
+# podman run -p 5000:5000 -it centos bash
+
+bash: error while loading shared libraries: /lib64/libc.so.6: cannot apply additional memory protection after relocation: Permission denied
+```
+
+For example, the admin sets up a spare disk to be mounted at `/src/containers`,
+and points storage.conf at this directory.
+
+
+#### Symptom
+
+SELinux blocks containers from using random locations for overlay storage.
+These directories need to be labeled with the same labels as if the content was
+under /var/lib/containers/storage.
+
+#### Solution
+
+Tell SELinux about the new containers storage by setting up an equivalence record.
+This tells SELinux to label content under the new path, as if it was stored
+under `/var/lib/containers/storage`.
+
+```
+semanage fcontext -a -e /var/lib/containers /srv/containers
+restorecon -R -v /src/containers
+```
+
+The semanage command above tells SELinux to setup the default labeling of
+`/srv/containers` to match `/var/lib/containers`. The `restorecon` command
+tells SELinux to apply the labels to the actual content.
+
+Now all new content created in these directories will automatically be created
+with the correct label.