diff options
30 files changed, 293 insertions, 256 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 7bc00dbb5..3516c7d61 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -67,9 +67,9 @@ env: RHEL_BASE_IMAGE: "rhel-guest-image-7-6-210-x86-64-qcow2-1548099756" #### - #### Default to NOT running in rootless-testing mode + #### Default to NOT operating in any special-case testing mode #### - ROOTLESS_USER: "" + SPECIALMODE: "none" # don't do anything special #### #### Credentials and other secret-sauces, decrypted at runtime when authorized. @@ -257,8 +257,8 @@ testing_task: master_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_master_failure.sh' -# This task executes tests as a regular user on a system -rootless_testing_task: +# This task executes tests under unique environments/conditions +special_testing_task: depends_on: - "gating" @@ -274,15 +274,14 @@ rootless_testing_task: image_name: "${FEDORA_CACHE_IMAGE_NAME}" env: - ROOTLESS_USER: "olympiclongjumpingwithjesus" + matrix: + SPECIALMODE: 'rootless' # See docs + SPECIALMODE: 'in_podman' # See docs 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 + integration_test_script: '$SCRIPT_BASE/integration_test.sh' on_failure: master_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_master_failure.sh' diff --git a/.papr.yml b/.papr.yml deleted file mode 100644 index ed20c6039..000000000 --- a/.papr.yml +++ /dev/null @@ -1,97 +0,0 @@ -branches: - - master - - auto - - try - -host: - distro: fedora/28/atomic - specs: - ram: 8192 - cpus: 4 -required: true -timeout: 90m - -tests: - - rpm-ostree usroverlay && rpm -Uvh https://kojipkgs.fedoraproject.org//packages/podman/0.10.1/1.gite4a1553.fc28/x86_64/podman-0.10.1-1.gite4a1553.fc28.x86_64.rpm - - CONTAINER_RUNTIME="podman" sh .papr_prepare.sh - -artifacts: - - build.log - -context: "FAH28 - Containerized (Podman in Podman)" - ---- - -host: - distro: centos/7/atomic/smoketested - specs: - ram: 8192 - cpus: 4 -extra-repos: - - name: epel - metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch - gpgcheck: 0 - - name: cri-o - baseurl: https://cbs.centos.org/repos/virt7-container-common-candidate/$basearch/os - gpgcheck: 0 - -required: true - -timeout: 90m - -tests: - - CONTAINER_RUNTIME="docker" sh .papr_prepare.sh - -artifacts: - - build.log - -context: "CAH 7-smoketested - Containerized (Podman in Docker)" - -#--- -# -#host: -# distro: centos/7/cloud -# specs: -# ram: 8192 -# cpus: 4 -#extra-repos: -# - name: epel -# metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch -# gpgcheck: 0 -# - name: cri-o -# baseurl: https://cbs.centos.org/repos/virt7-container-common-candidate/$basearch/os -# gpgcheck: 0 -# -#packages: -# - btrfs-progs-devel -# - glib2-devel -# - glibc-devel -# - glibc-static -# - git -# - go-md2man -# - gpgme-devel -# - libassuan-devel -# - libgpg-error-devel -# - libseccomp-devel -# - libselinux-devel -# - ostree-devel -# - pkgconfig -# - make -# - nc -# - go-compilers-golang-compiler -# - podman -# -#required: true -# -#timeout: 90m -# -#tests: -# - sed 's/^expand-check.*/expand-check=0/g' -i /etc/selinux/semanage.conf -# - sh .papr.sh -b -i -t -# -#artifacts: -# - build.log -# -#context: "CentOS 7 Cloud" -# -#--- diff --git a/.papr_prepare.sh b/.papr_prepare.sh deleted file mode 100644 index b93f7b91f..000000000 --- a/.papr_prepare.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -set -xeuo pipefail - -DIST=${DIST:=Fedora} -CONTAINER_RUNTIME=${CONTAINER_RUNTIME:=docker} -IMAGE=fedorapodmanbuild -if [[ ${DIST} != "Fedora" ]]; then - IMAGE=centospodmanbuild -fi - -# Since CRIU 3.11 has been pushed to Fedora 28 the checkpoint/restore -# test cases are actually run. As CRIU uses iptables to lock and unlock -# the network during checkpoint and restore it needs the following two -# modules loaded. -modprobe ip6table_nat || : -modprobe iptable_nat || : - -# Build the test image -${CONTAINER_RUNTIME} build -t ${IMAGE} -f Dockerfile.${DIST} . 2>build.log - -# Run the tests -${CONTAINER_RUNTIME} run --rm --privileged --net=host -v $PWD:/go/src/github.com/containers/libpod:Z --workdir /go/src/github.com/containers/libpod -e CGROUP_MANAGER=cgroupfs -e STORAGE_OPTIONS="--storage-driver=vfs" -e CRIO_ROOT="/go/src/github.com/containers/libpod" -e PODMAN_BINARY="/usr/bin/podman" -e CONMON_BINARY="/usr/libexec/podman/conmon" -e DIST=$DIST -e CONTAINER_RUNTIME=$CONTAINER_RUNTIME $IMAGE sh ./.papr.sh -b -i -t @@ -31,6 +31,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func DeleteUnusedImages() []string](#DeleteUnusedImages) +[func Diff(name: string) DiffInfo](#Diff) + [func ExportContainer(name: string, path: string) string](#ExportContainer) [func ExportImage(name: string, destination: string, compress: bool, tags: []string) string](#ExportImage) @@ -173,6 +175,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [type CreateResourceConfig](#CreateResourceConfig) +[type DiffInfo](#DiffInfo) + [type Event](#Event) [type IDMap](#IDMap) @@ -388,6 +392,11 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.DeleteUnusedImages ] } ~~~ +### <a name="Diff"></a>func Diff +<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> + +method Diff(name: [string](https://godoc.org/builtin#string)) [DiffInfo](#DiffInfo)</div> + ### <a name="ExportContainer"></a>func ExportContainer <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -1431,6 +1440,13 @@ pids_limit [int](https://godoc.org/builtin#int) shm_size [int](https://godoc.org/builtin#int) ulimit [[]string](#[]string) +### <a name="DiffInfo"></a>type DiffInfo + + + +path [string](https://godoc.org/builtin#string) + +changeType [string](https://godoc.org/builtin#string) ### <a name="Event"></a>type Event Event describes a libpod struct diff --git a/Dockerfile b/Dockerfile index 6d44b963f..28e0b88cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,6 +38,8 @@ RUN apt-get update && apt-get install -y \ socat \ lsof \ xz-utils \ + unzip \ + python3-yaml \ --no-install-recommends \ && apt-get clean diff --git a/Dockerfile.CentOS b/Dockerfile.centos index 605dc9df4..605dc9df4 100644 --- a/Dockerfile.CentOS +++ b/Dockerfile.centos diff --git a/Dockerfile.Fedora b/Dockerfile.fedora index e38e2e056..d4bcc11ea 100644 --- a/Dockerfile.Fedora +++ b/Dockerfile.fedora @@ -1,4 +1,4 @@ -FROM registry.fedoraproject.org/fedora:28 +FROM registry.fedoraproject.org/fedora:29 RUN dnf -y install btrfs-progs-devel \ atomic-registries \ @@ -5,7 +5,7 @@ Libpod provides a library for applications looking to use the Container Pod concept, popularized by Kubernetes. Libpod also contains the Pod Manager tool `(Podman)`. Podman manages pods, containers, container images, and container volumes. -* [Latest Version: 1.0.0](https://github.com/containers/libpod/releases/latest) +* [Latest Version: 1.2.0](https://github.com/containers/libpod/releases/latest) * [Continuous Integration:](contrib/cirrus/README.md) [![Build Status](https://api.cirrus-ci.com/github/containers/libpod.svg)](https://cirrus-ci.com/github/containers/libpod/master) ## Overview and scope diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index 875b2aec8..baa349e1a 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -14,7 +14,6 @@ func getMainCommands() []*cobra.Command { _attachCommand, _commitCommand, _createCommand, - _diffCommand, _execCommand, _generateCommand, _playCommand, @@ -58,7 +57,6 @@ func getContainerSubCommands() []*cobra.Command { _cleanupCommand, _commitCommand, _createCommand, - _diffCommand, _execCommand, _exportCommand, _killCommand, diff --git a/cmd/podman/container.go b/cmd/podman/container.go index 2e9cedbaa..743dec32f 100644 --- a/cmd/podman/container.go +++ b/cmd/podman/container.go @@ -52,6 +52,7 @@ var ( containerCommands = []*cobra.Command{ _containerExistsCommand, _contInspectSubCommand, + _diffCommand, _listSubCommand, _logsCommand, } diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go index e77e562d4..7f5a313f8 100644 --- a/cmd/podman/diff.go +++ b/cmd/podman/diff.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/pkg/adapter" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -86,18 +86,17 @@ func diffCmd(c *cliconfig.DiffValues) error { return errors.Errorf("container, image, or layer name must be specified: podman diff [options [...]] ID-NAME") } - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } defer runtime.Shutdown(false) to := c.InputArgs[0] - changes, err := runtime.GetDiff("", to) + changes, err := runtime.Diff(c, to) if err != nil { return errors.Wrapf(err, "could not get changes for %q", to) } - diffOutput := []diffOutputParams{} outputFormat := c.Format diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 4b1acd5a9..1ba58d1f3 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -39,6 +39,7 @@ var ( // implemented. var mainCommands = []*cobra.Command{ _buildCommand, + _diffCommand, _eventsCommand, _exportCommand, _historyCommand, diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index 01aa5312e..759a03b86 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -205,6 +205,10 @@ func psCmd(c *cliconfig.PsValues) error { span, _ := opentracing.StartSpanFromContext(Ctx, "psCmd") defer span.Finish() } + // TODO disable when single rootless userns merges + if c.Bool("size") && os.Geteuid() != 0 { + return errors.New("the --size option is not presently supported without root") + } var watch bool diff --git a/cmd/podman/run_test.go b/cmd/podman/run_test.go index a896f1dc7..0bf9cb4d9 100644 --- a/cmd/podman/run_test.go +++ b/cmd/podman/run_test.go @@ -8,6 +8,7 @@ import ( "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/pkg/inspect" cc "github.com/containers/libpod/pkg/spec" + "github.com/containers/libpod/pkg/sysinfo" "github.com/docker/go-units" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" spec "github.com/opencontainers/runtime-spec/specs-go" @@ -16,8 +17,9 @@ import ( ) var ( - cmd = []string{"podman", "test", "alpine"} - CLI *cliconfig.PodmanCommand + sysInfo = sysinfo.New(true) + cmd = []string{"podman", "test", "alpine"} + CLI *cliconfig.PodmanCommand ) // generates a mocked ImageData structure based on alpine @@ -100,6 +102,9 @@ func TestPIDsLimit(t *testing.T) { if runtime.GOOS != "linux" { t.Skip("seccomp, which is enabled by default, is only supported on Linux") } + if !sysInfo.PidsLimit { + t.Skip("running test not supported by the host system") + } args := []string{"--pids-limit", "22"} a := createCLI(args) a.InputArgs = args @@ -119,6 +124,9 @@ func TestBLKIOWeightDevice(t *testing.T) { if runtime.GOOS != "linux" { t.Skip("seccomp, which is enabled by default, is only supported on Linux") } + if !sysInfo.BlkioWeightDevice { + t.Skip("running test not supported by the host system") + } args := []string{"--blkio-weight-device", "/dev/zero:100"} a := createCLI(args) a.InputArgs = args @@ -137,6 +145,9 @@ func TestMemorySwap(t *testing.T) { if runtime.GOOS != "linux" { t.Skip("seccomp, which is enabled by default, is only supported on Linux") } + if !sysInfo.SwapLimit { + t.Skip("running test not supported by the host system") + } args := []string{"--memory-swap", "45m", "--memory", "40m"} a := createCLI(args) a.InputArgs = args diff --git a/cmd/podman/search.go b/cmd/podman/search.go index a10b9d419..e614887fc 100644 --- a/cmd/podman/search.go +++ b/cmd/podman/search.go @@ -83,11 +83,25 @@ func searchCmd(c *cliconfig.SearchValues) error { if len(results) == 0 { return nil } - out := formats.StdoutTemplateArray{Output: searchToGeneric(results), Template: format, Fields: genSearchOutputMap()} + out := formats.StdoutTemplateArray{Output: searchToGeneric(results), Template: format, Fields: searchHeaderMap()} formats.Writer(out).Out() return nil } +// searchHeaderMap returns the headers of a SearchResult. +func searchHeaderMap() map[string]string { + s := new(image.SearchResult) + v := reflect.Indirect(reflect.ValueOf(s)) + values := make(map[string]string, v.NumField()) + + for i := 0; i < v.NumField(); i++ { + key := v.Type().Field(i).Name + value := key + values[key] = strings.ToUpper(splitCamelCase(value)) + } + return values +} + func genSearchFormat(format string) string { if format != "" { // "\t" from the command line is not being recognized as a tab diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 5e996f46b..2ff06a6f6 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -461,6 +461,13 @@ type Event( type: string ) +type DiffInfo( + # path that is different + path: string, + # Add, Delete, Modify + changeType: string +) + # GetVersion returns version and build information of the podman service method GetVersion() -> ( version: string, @@ -1154,6 +1161,8 @@ method LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool) # GetEvents returns known libpod events filtered by the options provided. method GetEvents(filter: []string, since: string, until: string) -> (events: Event) +method Diff(name: string) -> (diffs: []DiffInfo) + # ImageNotFound means the image could not be found by the provided name or ID in local storage. error ImageNotFound (id: string, reason: string) diff --git a/contrib/cirrus/README.md b/contrib/cirrus/README.md index 0dabf5df6..ea358d2d7 100644 --- a/contrib/cirrus/README.md +++ b/contrib/cirrus/README.md @@ -63,26 +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 +### ``special_testing`` Task + +This task exercises podman under specialized environments or conditions. +The specific differences from the ``testing`` task depend upon the +contents of the ``$SPECIALMODE`` environment variable. + +| Value | Meaning | +| rootless | Setup a regular user to build/run integration tests. | +| in_podman | Setup a container image, build/run integration tests inside container | ***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. + `matrix: image_name` item. + +2. ``setup_environment.sh``: Mostly the same as + in ``testing`` task, then specialized depending on ``$SPECIALMODE``. + +3. Which tests and how they execute depends on ``$SPECIALMODE``. -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/.papr.sh b/contrib/cirrus/container_test.sh index c5aada904..e6c1a3a47 100644 --- a/.papr.sh +++ b/contrib/cirrus/container_test.sh @@ -1,7 +1,7 @@ #!/bin/bash set -xeuo pipefail -export GOPATH=/go +export GOPATH=/var/tmp/go export PATH=$HOME/gopath/bin:$PATH:$GOPATH/bin export GOSRC=$GOPATH/src/github.com/containers/libpod @@ -125,7 +125,7 @@ fi # Run integration tests if [ $integrationtest -eq 1 ]; then make TAGS="${TAGS}" test-binaries - make varlink_generate GOPATH=/go - make ginkgo GOPATH=/go $INTEGRATION_TEST_ENVS - make ginkgo-remote GOPATH=/go $INTEGRATION_TEST_ENVS + make varlink_generate + make ginkgo $INTEGRATION_TEST_ENVS + make ginkgo-remote $INTEGRATION_TEST_ENVS fi diff --git a/contrib/cirrus/integration_test.sh b/contrib/cirrus/integration_test.sh index 58c8af289..8a2507f38 100755 --- a/contrib/cirrus/integration_test.sh +++ b/contrib/cirrus/integration_test.sh @@ -5,33 +5,64 @@ source $(dirname $0)/lib.sh req_env_var " GOSRC $GOSRC +SCRIPT_BASE $SCRIPT_BASE OS_RELEASE_ID $OS_RELEASE_ID OS_RELEASE_VER $OS_RELEASE_VER +CONTAINER_RUNTIME $CONTAINER_RUNTIME " -record_timestamp "integration test start" +exit_handler() { + set +ex + record_timestamp "integration test end" +} +trap exit_handler EXIT -clean_env +record_timestamp "integration test start" -set -x cd "$GOSRC" -case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in - ubuntu-18) - make install PREFIX=/usr ETCDIR=/etc - make test-binaries - SKIP_USERNS=1 make localintegration - ;; - fedora-29) ;& # Continue to the next item - fedora-28) ;& - centos-7) ;& - rhel-7) - make install PREFIX=/usr ETCDIR=/etc - make podman-remote - install bin/podman-remote /usr/bin - make test-binaries - make localintegration - ;; - *) bad_os_id_ver ;; -esac - -record_timestamp "integration test end" + +if [[ "$SPECIALMODE" == "in_podman" ]] +then + set -x + ${CONTAINER_RUNTIME} run --rm --privileged --net=host \ + -v $GOSRC:$GOSRC:Z \ + --workdir $GOSRC \ + -e "CGROUP_MANAGER=cgroupfs" \ + -e "STORAGE_OPTIONS=--storage-driver=vfs" \ + -e "CRIO_ROOT=$GOSRC" \ + -e "PODMAN_BINARY=/usr/bin/podman" \ + -e "CONMON_BINARY=/usr/libexec/podman/conmon" \ + -e "DIST=$OS_RELEASE_ID" \ + -e "CONTAINER_RUNTIME=$CONTAINER_RUNTIME" \ + ${OS_RELEASE_ID}podmanbuild bash $GOSRC/$SCRIPT_BASE/container_test.sh -b -i -t + + exit $? +elif [[ "$SPECIALMODE" == "rootless" ]] +then + req_env_var "ROOTLESS_USER $ROOTLESS_USER" + set -x + ssh $ROOTLESS_USER@localhost \ + -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no \ + $GOSRC/$SCRIPT_BASE/rootless_test.sh + exit $? +else + set -x + make + make install PREFIX=/usr ETCDIR=/etc + make test-binaries + clean_env + + case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in + ubuntu-18) ;; + fedora-29) ;& # Continue to the next item + fedora-28) ;& + centos-7) ;& + rhel-7) + make podman-remote + install bin/podman-remote /usr/bin + ;; + *) bad_os_id_ver ;; + esac + make localintegration + exit $? +fi diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index e941610e2..6c45b2c5d 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -18,6 +18,8 @@ CIRRUS_BUILD_ID=${CIRRUS_BUILD_ID:-DEADBEEF} # a human CIRRUS_BASE_SHA=${CIRRUS_BASE_SHA:-HEAD} CIRRUS_CHANGE_IN_REPO=${CIRRUS_CHANGE_IN_REPO:-FETCH_HEAD} TIMESTAMPS_FILEPATH="${TIMESTAMPS_FILEPATH:-/var/tmp/timestamps}" +SPECIALMODE="${SPECIALMODE:-none}" +export CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-podman} if ! [[ "$PATH" =~ "/usr/local/bin" ]] then @@ -81,6 +83,7 @@ CIRRUS_USER_COLLABORATOR $CIRRUS_USER_COLLABORATOR CIRRUS_USER_PERMISSION $CIRRUS_USER_PERMISSION CIRRUS_WORKING_DIR $CIRRUS_WORKING_DIR CIRRUS_HTTP_CACHE_HOST $CIRRUS_HTTP_CACHE_HOST +SPECIALMODE $SPECIALMODE $(go env) PACKER_BUILDS $PACKER_BUILDS " | while read NAME VALUE @@ -127,15 +130,6 @@ bad_os_id_ver() { exit 42 } -run_rootless() { - if [[ -z "$ROOTLESS_USER" ]] - then - return 1 - else - return 0 - fi -} - stub() { echo "STUB: Pretending to do $1" } @@ -179,6 +173,13 @@ setup_rootless() { return 0 fi + # Only do this once + cd $GOSRC + make install.catatonit + go get github.com/onsi/ginkgo/ginkgo + go get github.com/onsi/gomega/... + dnf -y update runc + # Guarantee independence from specific values ROOTLESS_UID=$[RANDOM+1000] ROOTLESS_GID=$[RANDOM+1000] diff --git a/contrib/cirrus/rootless_test.sh b/contrib/cirrus/rootless_test.sh index d0e2ceb95..88b38f45b 100755 --- a/contrib/cirrus/rootless_test.sh +++ b/contrib/cirrus/rootless_test.sh @@ -12,9 +12,9 @@ OS_RELEASE_ID $OS_RELEASE_ID OS_RELEASE_VER $OS_RELEASE_VER " -if ! run_rootless +if [[ "$UID" == "0" ]] then - echo "Error: Expected rootless env. vars not set or empty" + echo "Error: Expected to be running as a regular user" exit 1 fi @@ -24,16 +24,9 @@ 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 - make varlink_generate - make test-binaries - make ginkgo - ;; - *) bad_os_id_ver ;; -esac +make +make varlink_generate +make test-binaries +make ginkgo record_timestamp "rootless test end" diff --git a/contrib/cirrus/setup_container_environment.sh b/contrib/cirrus/setup_container_environment.sh new file mode 100755 index 000000000..23df4fe8b --- /dev/null +++ b/contrib/cirrus/setup_container_environment.sh @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +source $(dirname $0)/lib.sh + +req_env_var " +GOSRC $GOSRC +OS_RELEASE_ID $OS_RELEASE_ID +CONTAINER_RUNTIME $CONTAINER_RUNTIME +" + +DIST=$OS_RELEASE_ID +IMAGE=${DIST}podmanbuild + +# Since CRIU 3.11 has been pushed to Fedora 28 the checkpoint/restore +# test cases are actually run. As CRIU uses iptables to lock and unlock +# the network during checkpoint and restore it needs the following two +# modules loaded. +modprobe ip6table_nat || : +modprobe iptable_nat || : + +# Build the test image +${CONTAINER_RUNTIME} build -t ${IMAGE} -f Dockerfile.${DIST} . diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index 96d0e1b55..55706954e 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -43,7 +43,6 @@ 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 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"' \ @@ -75,14 +74,17 @@ then # Reload to incorporate any changes from above source "$SCRIPT_BASE/lib.sh" - if run_rootless - then - setup_rootless - make install.catatonit - go get github.com/onsi/ginkgo/ginkgo - go get github.com/onsi/gomega/... - dnf -y update runc - fi + case "$SPECIALMODE" in + rootless) + X=$(echo "export ROOTLESS_USER='some${RANDOM}dude'" | \ + tee -a "$HOME/$ENVLIB") && eval "$X" && echo "$X" + setup_rootless + ;; + in_podman) # Assumed to be Fedora + dnf install -y podman buildah + $SCRIPT_BASE/setup_container_environment.sh + ;; + esac fi show_env_vars diff --git a/contrib/cirrus/unit_test.sh b/contrib/cirrus/unit_test.sh index fd9e82509..4ace19d10 100755 --- a/contrib/cirrus/unit_test.sh +++ b/contrib/cirrus/unit_test.sh @@ -15,17 +15,8 @@ clean_env set -x cd "$GOSRC" -case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in - ubuntu-18) ;& # Continue to the next item - fedora-29) ;& - fedora-28) ;& - centos-7) ;& - rhel-7) - make install.tools - make localunit - make - ;; - *) bad_os_id_ver ;; -esac +make install.tools +make localunit +make record_timestamp "unit test end" diff --git a/libpod/image/search.go b/libpod/image/search.go index 2c66ce284..03a67636b 100644 --- a/libpod/image/search.go +++ b/libpod/image/search.go @@ -2,7 +2,6 @@ package image import ( "context" - "reflect" "strconv" "strings" "sync" @@ -10,7 +9,6 @@ import ( "github.com/containers/image/docker" "github.com/containers/image/types" sysreg "github.com/containers/libpod/pkg/registries" - "github.com/fatih/camelcase" "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" @@ -63,24 +61,6 @@ type SearchFilter struct { IsOfficial types.OptionalBool } -func splitCamelCase(src string) string { - entries := camelcase.Split(src) - return strings.Join(entries, " ") -} - -// HeaderMap returns the headers of a SearchResult. -func (s *SearchResult) HeaderMap() map[string]string { - v := reflect.Indirect(reflect.ValueOf(s)) - values := make(map[string]string, v.NumField()) - - for i := 0; i < v.NumField(); i++ { - key := v.Type().Field(i).Name - value := key - values[key] = strings.ToUpper(splitCamelCase(value)) - } - return values -} - // SearchImages searches images based on term and the specified SearchOptions // in all registries. func SearchImages(term string, options SearchOptions) ([]SearchResult, error) { diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go index f4d564cf8..182a04044 100644 --- a/pkg/adapter/runtime.go +++ b/pkg/adapter/runtime.go @@ -22,6 +22,7 @@ import ( "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" ) @@ -357,3 +358,8 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error { } return nil } + +// Diff shows the difference in two objects +func (r *LocalRuntime) Diff(c *cliconfig.DiffValues, to string) ([]archive.Change, error) { + return r.Runtime.GetDiff("", to) +} diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index 48d7eb986..978c9ffd8 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -824,3 +824,30 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error { } return nil } + +// Diff ... +func (r *LocalRuntime) Diff(c *cliconfig.DiffValues, to string) ([]archive.Change, error) { + var changes []archive.Change + reply, err := iopodman.Diff().Call(r.Conn, to) + if err != nil { + return nil, err + } + for _, change := range reply { + changes = append(changes, archive.Change{Path: change.Path, Kind: stringToChangeType(change.ChangeType)}) + } + return changes, nil +} + +func stringToChangeType(change string) archive.ChangeType { + switch change { + case "A": + return archive.ChangeAdd + case "D": + return archive.ChangeDelete + default: + logrus.Errorf("'%s' is unknown archive type", change) + fallthrough + case "C": + return archive.ChangeModify + } +} diff --git a/pkg/annotations/annotations.go b/pkg/annotations/annotations.go index 008cca7ee..fe2591a0c 100644 --- a/pkg/annotations/annotations.go +++ b/pkg/annotations/annotations.go @@ -19,9 +19,18 @@ const ( // HostName is the container host name annotation HostName = "io.kubernetes.cri-o.HostName" + // CgroupParent is the sandbox cgroup parent + CgroupParent = "io.kubernetes.cri-o.CgroupParent" + // IP is the container ipv4 or ipv6 address IP = "io.kubernetes.cri-o.IP" + // NamespaceOptions store the options for namespaces + NamespaceOptions = "io.kubernetes.cri-o.NamespaceOptions" + + // SeccompProfilePath is the node seccomp profile path + SeccompProfilePath = "io.kubernetes.cri-o.SeccompProfilePath" + // Image is the container image ID annotation Image = "io.kubernetes.cri-o.Image" @@ -34,6 +43,9 @@ const ( // KubeName is the kubernetes name annotation KubeName = "io.kubernetes.cri-o.KubeName" + // PortMappings holds the port mappings for the sandbox + PortMappings = "io.kubernetes.cri-o.PortMappings" + // Labels are the kubernetes labels annotation Labels = "io.kubernetes.cri-o.Labels" @@ -46,6 +58,9 @@ const ( // Name is the pod name annotation Name = "io.kubernetes.cri-o.Name" + // Namespace is the pod namespace annotation + Namespace = "io.kubernetes.cri-o.Namespace" + // PrivilegedRuntime is the annotation for the privileged runtime path PrivilegedRuntime = "io.kubernetes.cri-o.PrivilegedRuntime" @@ -67,8 +82,8 @@ const ( // MountPoint is the mount point of the container rootfs MountPoint = "io.kubernetes.cri-o.MountPoint" - // TrustedSandbox is the annotation for trusted sandboxes - TrustedSandbox = "io.kubernetes.cri-o.TrustedSandbox" + // RuntimeHandler is the annotation for runtime handler + RuntimeHandler = "io.kubernetes.cri-o.RuntimeHandler" // TTY is the terminal path annotation TTY = "io.kubernetes.cri-o.TTY" @@ -79,8 +94,14 @@ const ( // StdinOnce is the stdin_once annotation StdinOnce = "io.kubernetes.cri-o.StdinOnce" - // Volumes is the volumes annotation + // Volumes is the volumes annotatoin Volumes = "io.kubernetes.cri-o.Volumes" + + // HostNetwork indicates whether the host network namespace is used or not + HostNetwork = "io.kubernetes.cri-o.HostNetwork" + + // CNIResult is the JSON string representation of the Result from CNI + CNIResult = "io.kubernetes.cri-o.CNIResult" ) // ContainerType values diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 0ca867410..63d500204 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -910,3 +910,16 @@ func (i *LibpodAPI) LoadImage(call iopodman.VarlinkCall, name, inputFile string, } return call.ReplyLoadImage(br) } + +// Diff ... +func (i *LibpodAPI) Diff(call iopodman.VarlinkCall, name string) error { + var response []iopodman.DiffInfo + changes, err := i.Runtime.GetDiff("", name) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + for _, change := range changes { + response = append(response, iopodman.DiffInfo{Path: change.Path, ChangeType: change.Kind.String()}) + } + return call.ReplyDiff(response) +} diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index f9d7abe8f..5da3d563b 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -3,6 +3,7 @@ package integration import ( + "fmt" "os" . "github.com/containers/libpod/test/utils" @@ -95,28 +96,41 @@ var _ = Describe("Podman pod rm", func() { }) It("podman pod rm -a doesn't remove a running container", func() { + fmt.Printf("To start, there are %d pods\n", podmanTest.NumberOfPods()) _, ec, podid1 := podmanTest.CreatePod("") Expect(ec).To(Equal(0)) _, ec, _ = podmanTest.CreatePod("") Expect(ec).To(Equal(0)) + fmt.Printf("Started %d pods\n", podmanTest.NumberOfPods()) session := podmanTest.RunTopContainerInPod("", podid1) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + podmanTest.WaitForContainer() + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + fmt.Printf("Started container running in one pod") + num_pods := podmanTest.NumberOfPods() + Expect(num_pods).To(Equal(2)) + ps := podmanTest.Podman([]string{"pod", "ps"}) + ps.WaitWithDefaultTimeout() + fmt.Printf("Current %d pod(s):\n%s\n", num_pods, ps.OutputToString()) + + fmt.Printf("Removing all empty pods\n") result := podmanTest.Podman([]string{"pod", "rm", "-a"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Not(Equal(0))) - - result = podmanTest.Podman([]string{"ps", "-q"}) - result.WaitWithDefaultTimeout() - Expect(len(result.OutputToStringArray())).To(Equal(1)) - - // one pod should have been deleted - result = podmanTest.Podman([]string{"pod", "ps", "-q"}) - result.WaitWithDefaultTimeout() - Expect(len(result.OutputToStringArray())).To(Equal(1)) + foundExpectedError, _ := result.ErrorGrepString("contains containers and cannot be removed") + Expect(foundExpectedError).To(Equal(true)) + + num_pods = podmanTest.NumberOfPods() + ps = podmanTest.Podman([]string{"pod", "ps"}) + ps.WaitWithDefaultTimeout() + fmt.Printf("Final %d pod(s):\n%s\n", num_pods, ps.OutputToString()) + Expect(num_pods).To(Equal(1)) + // Confirm top container still running inside remaining pod + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) It("podman pod rm -fa removes everything", func() { |