diff options
-rw-r--r-- | .cirrus.yml | 8 | ||||
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | cmd/podman/import.go | 8 | ||||
-rw-r--r-- | cmd/podman/shared/parse/parse.go | 10 | ||||
-rwxr-xr-x | contrib/cirrus/build_vm_images.sh | 15 | ||||
-rwxr-xr-x | contrib/cirrus/check_image.sh | 32 | ||||
-rw-r--r-- | contrib/cirrus/lib.sh | 13 | ||||
-rwxr-xr-x | contrib/cirrus/setup_environment.sh | 9 | ||||
-rw-r--r-- | docs/links/podman-container-cp.1 | 1 | ||||
-rw-r--r-- | docs/links/podman-container-init.1 | 1 | ||||
-rw-r--r-- | docs/links/podman-help.1 | 1 | ||||
-rw-r--r-- | docs/podman-remote.1.md | 141 | ||||
-rwxr-xr-x | docs/podman-remote.sh | 11 | ||||
-rw-r--r-- | docs/podman-run.1.md | 3 | ||||
-rw-r--r-- | libpod/image/image.go | 5 | ||||
-rw-r--r-- | pkg/hooks/hooks.go | 24 | ||||
-rw-r--r-- | pkg/hooks/monitor.go | 49 | ||||
-rw-r--r-- | pkg/hooks/monitor_test.go | 25 | ||||
-rw-r--r-- | pkg/hooks/read.go | 11 | ||||
-rw-r--r-- | test/e2e/common_test.go | 5 |
21 files changed, 279 insertions, 117 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index cd6bac265..78b00c879 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -40,11 +40,6 @@ env: #### base-images (pre-existing in GCE) #### BUILT_IMAGE_SUFFIX: "-${CIRRUS_REPO_NAME}-${CIRRUS_BUILD_ID}" - # Git commits to use while building dependencies into cache-images - FEDORA_CNI_COMMIT: "412b6d31280682bb4fab4446f113c22ff1886554" - CNI_COMMIT: "7480240de9749f9a0a5c8614b17f1f03e0c06ab9" - CONMON_COMMIT: "6f3572558b97bc60dd8f8c7f0807748e6ce2c440" - CRIU_COMMIT: "c74b83cd49c00589c0c0468ba5fe685b67fdbd0a" # Special image w/ nested-libvirt + tools for creating new cache and base images IMAGE_BUILDER_CACHE_IMAGE_NAME: "image-builder-image-1541772081" @@ -540,6 +535,9 @@ success_task: release_task: + # Never do this when building images + only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + # TODO: Uncomment both to not affect pass/fail status of entire job? # allow_failures: $CI == "true" # skip_notifications: $CI == "true" diff --git a/.gitignore b/.gitignore index b26674172..4f1100d8e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ /.artifacts/ /_output/ +/brew /conmon/conmon.o /docs/*.[158] /docs/*.[158].gz +/docs/remote *.o *.orig /pause/pause.o @@ -19,3 +21,4 @@ __pycache__ .gopathok test/e2e/e2e.coverprofile /podman*zip +podman*.tar.gz @@ -75,11 +75,13 @@ LIBSECCOMP_COMMIT := release-2.3 GINKGOTIMEOUT ?= -timeout=90m RELEASE_VERSION ?= $(shell git fetch --tags && git describe HEAD 2> /dev/null) +RELEASE_NUMBER ?= $(shell echo $(RELEASE_VERSION) | sed 's/-.*//') RELEASE_DIST ?= $(shell ( source /etc/os-release; echo $$ID )) RELEASE_DIST_VER ?= $(shell ( source /etc/os-release; echo $$VERSION_ID | cut -d '.' -f 1)) RELEASE_ARCH ?= $(shell go env GOARCH 2> /dev/null) RELEASE_BASENAME := $(shell basename $(PROJECT)) + # If GOPATH not specified, use one in the local directory ifeq ($(GOPATH),) export GOPATH := $(CURDIR)/_output @@ -143,7 +145,6 @@ gofmt: ## Verify the source code gofmt find . -name '*.go' ! -path './vendor/*' -exec gofmt -s -w {} \+ git diff --exit-code - test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go) $(GO) build -ldflags '$(LDFLAGS)' -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/checkseccomp @@ -175,8 +176,10 @@ clean: ## Clean artifacts .gopathok \ _output \ podman*.zip \ + podman*.tar.gz \ bin \ build \ + docs/remote \ test/checkseccomp/checkseccomp \ test/goecho/goecho \ test/testdata/redis-image \ @@ -292,6 +295,22 @@ $(MANPAGES): %: %.md .gopathok docs: $(MANPAGES) ## Generate documentation +install-podman-remote-docs: docs + @(cd docs; ./podman-remote.sh ./remote) + + +brew-pkg: install-podman-remote-docs podman-remote-darwin + @mkdir -p ./brew + @cp ./bin/podman-remote-darwin ./brew/podman + @cp -r ./docs/remote ./brew/docs/ + @cp docs/podman-remote.1 ./brew/docs/podman.1 + @sed -i 's/podman\\*-remote/podman/g' ./brew/docs/podman.1 + @sed -i 's/Podman\\*-remote/Podman\ for\ Mac/g' ./brew/docs/podman.1 + @sed -i 's/podman\.conf/podman\-remote\.conf/g' ./brew/docs/podman.1 + @sed -i 's/A\ remote\ CLI\ for\ Podman\:\ //g' ./brew/docs/podman.1 + tar -czvf podman-${RELEASE_NUMBER}.tar.gz ./brew + @rm -rf ./brew + docker-docs: docs (cd docs; ./dckrman.sh *.1) diff --git a/cmd/podman/import.go b/cmd/podman/import.go index 70ea167cb..d49792f27 100644 --- a/cmd/podman/import.go +++ b/cmd/podman/import.go @@ -6,6 +6,7 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared/parse" "github.com/containers/libpod/pkg/adapter" + multierror "github.com/hashicorp/go-multierror" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -69,8 +70,11 @@ func importCmd(c *cliconfig.ImportValues) error { return errors.Errorf("too many arguments. Usage TARBALL [REFERENCE]") } - if err := parse.ValidateFileName(source); err != nil { - return err + errFileName := parse.ValidateFileName(source) + errURL := parse.ValidURL(source) + + if errFileName != nil && errURL != nil { + return multierror.Append(errFileName, errURL) } quiet := c.Quiet diff --git a/cmd/podman/shared/parse/parse.go b/cmd/podman/shared/parse/parse.go index a77002235..9fbc92fc3 100644 --- a/cmd/podman/shared/parse/parse.go +++ b/cmd/podman/shared/parse/parse.go @@ -7,6 +7,7 @@ import ( "bufio" "fmt" "net" + "net/url" "os" "regexp" "strings" @@ -162,3 +163,12 @@ func ValidateFileName(filename string) error { } return nil } + +// ValidURL checks a string urlStr is a url or not +func ValidURL(urlStr string) error { + _, err := url.ParseRequestURI(urlStr) + if err != nil { + return errors.Wrapf(err, "invalid url path: %q", urlStr) + } + return nil +} diff --git a/contrib/cirrus/build_vm_images.sh b/contrib/cirrus/build_vm_images.sh index 74b10158c..dd5182c37 100755 --- a/contrib/cirrus/build_vm_images.sh +++ b/contrib/cirrus/build_vm_images.sh @@ -32,7 +32,7 @@ for base_image_var in $BASE_IMAGE_VARS do # See entrypoint.sh in contrib/imgts and contrib/imgprune # These updates can take a while, run them in the background, check later - gcloud compute images update "$image" \ + gcloud compute images update \ --update-labels=last-used=$(date +%s) \ --update-labels=build-id=$CIRRUS_BUILD_ID \ --update-labels=repo-ref=$CIRRUS_CHANGE_IN_REPO \ @@ -62,17 +62,6 @@ URI="gs://packer-import${POST_MERGE_BUCKET_SUFFIX}/manifest${BUILT_IMAGE_SUFFIX} gsutil cp packer-manifest.json "$URI" # Ensure any background 'gcloud compute images update' processes finish -set +e # need 'wait' exit code to avoid race -while [[ -n "$(jobs)" ]] -do - wait -n - RET=$? - if [[ "$RET" -eq "127" ]] || \ # Avoid TOCTOU race w/ jobs + wait - [[ "$RET" -eq "0" ]] - then - continue - fi - die $RET "Required base-image metadata update failed" -done +wait # CentOS has no -n option :( echo "Finished. A JSON manifest of produced images is available at $URI" diff --git a/contrib/cirrus/check_image.sh b/contrib/cirrus/check_image.sh index 690a38119..22ed1ddc4 100755 --- a/contrib/cirrus/check_image.sh +++ b/contrib/cirrus/check_image.sh @@ -4,26 +4,26 @@ set -eo pipefail source $(dirname $0)/lib.sh -RET=0 +NFAILS=0 echo "Validating VM image" MIN_SLASH_GIGS=50 read SLASH_DEVICE SLASH_FSTYPE SLASH_SIZE JUNK <<<$(findmnt --df --first-only --noheadings / | cut -d '.' -f 1) SLASH_SIZE_GIGS=$(echo "$SLASH_SIZE" | sed -r -e 's/G|g//') -item_test "Minimum available disk space" $SLASH_SIZE_GIGS -gt $MIN_SLASH_GIGS || let "RET+=1" +item_test "Minimum available disk space" $SLASH_SIZE_GIGS -gt $MIN_SLASH_GIGS || let "NFAILS+=1" MIN_MEM_MB=2000 read JUNK TOTAL USED MEM_FREE JUNK <<<$(free -tm | tail -1) -item_test 'Minimum available memory' $MEM_FREE -ge $MIN_MEM_MB || let "RET+=1" +item_test 'Minimum available memory' $MEM_FREE -ge $MIN_MEM_MB || let "NFAILS+=1" # We're testing a custom-built podman; make sure there isn't a distro-provided # binary anywhere; that could potentially taint our results. -item_test "remove_packaged_podman_files() did it's job" -z "$(type -P podman)" || let "RET+=1" +item_test "remove_packaged_podman_files() did it's job" -z "$(type -P podman)" || let "NFAILS+=1" MIN_ZIP_VER='3.0' VER_RE='.+([[:digit:]]+\.[[:digit:]]+).+' ACTUAL_VER=$(zip --version 2>&1 | egrep -m 1 "Zip$VER_RE" | sed -r -e "s/$VER_RE/\\1/") -item_test "minimum zip version" "$MIN_ZIP_VER" = $(echo -e "$MIN_ZIP_VER\n$ACTUAL_VER" | sort -V | head -1) || let "RET+=1" +item_test "minimum zip version" "$MIN_ZIP_VER" = $(echo -e "$MIN_ZIP_VER\n$ACTUAL_VER" | sort -V | head -1) || let "NFAILS+=1" for REQ_UNIT in google-accounts-daemon.service \ google-clock-skew-daemon.service \ @@ -33,13 +33,21 @@ for REQ_UNIT in google-accounts-daemon.service \ google-startup-scripts.service do item_test "required $REQ_UNIT enabled" \ - "$(systemctl list-unit-files --no-legend $REQ_UNIT)" = "$REQ_UNIT enabled" || let "RET+=1" + "$(systemctl list-unit-files --no-legend $REQ_UNIT)" = "$REQ_UNIT enabled" || let "NFAILS+=1" done -# Exits zero if any unit matching pattern is running -UNIT_STATUS=$(systemctl is-active $EVIL_UNITS; echo $?) -item_test "No interfering background units are active:" \ - "$UNIT_STATUS" -ne "0" || let "RET+=1" +for evil_unit in $EVIL_UNITS +do + # Exits zero if any unit matching pattern is running + unit_status=$(systemctl is-active $evil_unit &> /dev/null; echo $?) + item_test "No $evil_unit unit is present or active:" "$unit_status" -ne "0" || let "NFAILS+=1" +done + +if [[ "$OS_RELEASE_ID" == "ubuntu" ]] && [[ -x "/usr/lib/cri-o-runc/sbin/runc" ]] +then + SAMESAME=$(diff --brief /usr/lib/cri-o-runc/sbin/runc /usr/bin/runc &> /dev/null; echo $?) + item_test "On ubuntu /usr/bin/runc is /usr/lib/cri-o-runc/sbin/runc" "$SAMESAME" -eq "0" || let "NFAILS+=1" +fi -echo "Total failed tests: $RET" -exit $RET +echo "Total failed tests: $NFAILS" +exit $NFAILS diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index a9da3f4ce..737ca3c01 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -358,11 +358,14 @@ systemd_banish(){ set +e # Not all of these exist on every platform for unit in $EVIL_UNITS do - ooe.sh sudo systemctl stop $unit - ooe.sh sudo systemctl disable $unit - ooe.sh sudo systemctl disable $unit.timer - ooe.sh sudo systemctl mask $unit - ooe.sh sudo systemctl mask $unit.timer + echo "Banishing $unit (ignoring errors)" + ( + sudo systemctl stop $unit + sudo systemctl disable $unit + sudo systemctl disable $unit.timer + sudo systemctl mask $unit + sudo systemctl mask $unit.timer + ) &> /dev/null done set -e } diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index e49bb98fe..2230684ac 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -34,7 +34,14 @@ done # (see docs). cd "${GOSRC}/" case "${OS_REL_VER}" in - ubuntu-18) ;; + ubuntu-18) + CRIO_RUNC_PATH="/usr/lib/cri-o-runc/sbin/runc" + if dpkg -L cri-o-runc | grep -m 1 -q "$CRIO_RUNC_PATH" + then + echo "Linking $CRIO_RUNC_PATH to /usr/bin/runc for ease of testing." + ln -f "$CRIO_RUNC_PATH" "/usr/bin/runc" + fi + ;; fedora-30) ;; fedora-29) ;; centos-7) # Current VM is an image-builder-image no local podman/testing diff --git a/docs/links/podman-container-cp.1 b/docs/links/podman-container-cp.1 new file mode 100644 index 000000000..6ad859c84 --- /dev/null +++ b/docs/links/podman-container-cp.1 @@ -0,0 +1 @@ +.so man1/podman-cp.1 diff --git a/docs/links/podman-container-init.1 b/docs/links/podman-container-init.1 new file mode 100644 index 000000000..3a8bee249 --- /dev/null +++ b/docs/links/podman-container-init.1 @@ -0,0 +1 @@ +.so man1/podman-init.1 diff --git a/docs/links/podman-help.1 b/docs/links/podman-help.1 new file mode 100644 index 000000000..6b7954b0d --- /dev/null +++ b/docs/links/podman-help.1 @@ -0,0 +1 @@ +.so man1/podman.1 diff --git a/docs/podman-remote.1.md b/docs/podman-remote.1.md new file mode 100644 index 000000000..84042a842 --- /dev/null +++ b/docs/podman-remote.1.md @@ -0,0 +1,141 @@ +% podman-remote(1) + +## NAME +podman-remote - A remote CLI for Podman: A Simple management tool for pods, containers and images. + +## SYNOPSIS +**podman-remote** [*options*] *command* + +## DESCRIPTION +Podman (Pod Manager) is a fully featured container engine that is a simple daemonless tool. +Podman provides a Docker-CLI comparable command line that eases the transition from other +container engines and allows the management of pods, containers and images. Simply put: `alias docker=podman`. +Most Podman commands can be run as a regular user, without requiring additional +privileges. + +Podman uses Buildah(1) internally to create container images. Both tools share image +(not container) storage, hence each can use or manipulate images (but not containers) +created by the other. + +Podman-remote provides a local client interacting with a Podman backend node through a varlink ssh connection. In this context, a Podman node is a Linux system with Podman installed on it and the varlink service activated. Credentials for this session can be passed in using flags, enviroment variables, or in `podman-remote.conf` + +**podman [GLOBAL OPTIONS]** + +## GLOBAL OPTIONS + +**--connection**=*name* + +Remote connection name + +**--help**, **-h** + +Print usage statement + +**--log-level**=*level* + +Log messages above specified level: debug, info, warn, error (default), fatal or panic + +**--remote-config-path**=*path* + +Alternate path for configuration file + +**--remote-host**=*ip* + +Remote host IP + +**--syslog** + +Output logging information to syslog as well as the console + +**--username**=*string* + +Username on the remote host (defaults to current username) + +**--version** + +Print the version + +## Exit Status + +The exit code from `podman` gives information about why the container +failed to run or why it exited. When `podman` commands exit with a non-zero code, +the exit codes follow the `chroot` standard, see below: + +**_125_** if the error is with podman **_itself_** + + $ podman run --foo busybox; echo $? + Error: unknown flag: --foo + 125 + +**_126_** if executing a **_contained command_** and the **_command_** cannot be invoked + + $ podman run busybox /etc; echo $? + Error: container_linux.go:346: starting container process caused "exec: \"/etc\": permission denied": OCI runtime error + 126 + +**_127_** if executing a **_contained command_** and the **_command_** cannot be found + $ podman run busybox foo; echo $? + Error: container_linux.go:346: starting container process caused "exec: \"foo\": executable file not found in $PATH": OCI runtime error + 127 + +**_Exit code_** of **_contained command_** otherwise + + $ podman run busybox /bin/sh -c 'exit 3' + # 3 + + +## COMMANDS + +| Command | Description | +| ------------------------------------------------ | --------------------------------------------------------------------------- | +| [podman-attach(1)](podman-attach.1.md) | Attach to a running container. | +| [podman-build(1)](podman-build.1.md) | Build a container image using a Dockerfile. | +| [podman-commit(1)](podman-commit.1.md) | Create new image based on the changed container. | +| [podman-container(1)](podman-container.1.md) | Manage containers. | +| [podman-cp(1)](podman-cp.1.md) | Copy files/folders between a container and the local filesystem. | +| [podman-create(1)](podman-create.1.md) | Create a new container. | +| [podman-diff(1)](podman-diff.1.md) | Inspect changes on a container or image's filesystem. | +| [podman-events(1)](podman-events.1.md) | Monitor Podman events | +| [podman-export(1)](podman-export.1.md) | Export a container's filesystem contents as a tar archive. | +| [podman-generate(1)](podman-generate.1.md) | Generate structured data based for a containers and pods. | +| [podman-healthcheck(1)](podman-healthcheck.1.md) | Manage healthchecks for containers | +| [podman-history(1)](podman-history.1.md) | Show the history of an image. | +| [podman-image(1)](podman-image.1.md) | Manage images. | +| [podman-images(1)](podman-images.1.md) | List images in local storage. | +| [podman-import(1)](podman-import.1.md) | Import a tarball and save it as a filesystem image. | +| [podman-info(1)](podman-info.1.md) | Displays Podman related system information. | +| [podman-init(1)](podman-init.1.md) | Initialize a container | +| [podman-inspect(1)](podman-inspect.1.md) | Display a container or image's configuration. | +| [podman-kill(1)](podman-kill.1.md) | Kill the main process in one or more containers. | +| [podman-load(1)](podman-load.1.md) | Load an image from a container image archive into container storage. | +| [podman-logs(1)](podman-logs.1.md) | Display the logs of a container. | +| [podman-pause(1)](podman-pause.1.md) | Pause one or more containers. | +| [podman-pod(1)](podman-pod.1.md) | Management tool for groups of containers, called pods. | +| [podman-port(1)](podman-port.1.md) | List port mappings for a container. | +| [podman-ps(1)](podman-ps.1.md) | Prints out information about containers. | +| [podman-pull(1)](podman-pull.1.md) | Pull an image from a registry. | +| [podman-push(1)](podman-push.1.md) | Push an image from local storage to elsewhere. | +| [podman-restart(1)](podman-restart.1.md) | Restart one or more containers. | +| [podman-rm(1)](podman-rm.1.md) | Remove one or more containers. | +| [podman-rmi(1)](podman-rmi.1.md) | Removes one or more locally stored images. | +| [podman-run(1)](podman-run.1.md) | Run a command in a new container. | +| [podman-save(1)](podman-save.1.md) | Save an image to a container archive. | +| [podman-start(1)](podman-start.1.md) | Start one or more containers. | +| [podman-stop(1)](podman-stop.1.md) | Stop one or more running containers. | +| [podman-system(1)](podman-system.1.md) | Manage podman. | +| [podman-tag(1)](podman-tag.1.md) | Add an additional name to a local image. | +| [podman-top(1)](podman-top.1.md) | Display the running processes of a container. | +| [podman-unpause(1)](podman-unpause.1.md) | Unpause one or more containers. | +| [podman-version(1)](podman-version.1.md) | Display the Podman version information. | +| [podman-volume(1)](podman-volume.1.md) | Manage Volumes. | + +## FILES + +**podman-remote.conf** (`~/.config/containers/podman-remote.conf`) + + The podman-remote.conf file is the default configuration file for the podman + remote client. It is in the TOML format. It is primarily used to keep track + of the user's remote connections. + +## SEE ALSO +`podman-remote.conf(5)` diff --git a/docs/podman-remote.sh b/docs/podman-remote.sh new file mode 100755 index 000000000..db3bb6d50 --- /dev/null +++ b/docs/podman-remote.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +BREWDIR=$1 +mkdir -p $BREWDIR +docs() { +[ -z $1 ] || type="-$1" +for i in $(podman-remote $1 --help | sed -n '/^Available Commands:/,/^Flags:/p'| sed -e '1d;$d' -e '/^$/d' | awk '{print $1}'); do install podman$type-$i.1 $BREWDIR 2>/dev/null || install links/podman$type-$i.1 $BREWDIR; done +} +docs + +for cmd in 'container image pod volume'; do docs $cmd; done diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md index 8d7d2c287..f5f44fad4 100644 --- a/docs/podman-run.1.md +++ b/docs/podman-run.1.md @@ -646,6 +646,9 @@ If specified, the first argument refers to an exploded container on the file sys This is useful to run a container without requiring any image management, the rootfs of the container is assumed to be managed externally. +Note: On `SELinux` systems, the rootfs needs the correct label, which is by default +`unconfined_u:object_r:container_file_t`. + **--security-opt**=*option* Security Options diff --git a/libpod/image/image.go b/libpod/image/image.go index db50e3dbd..068491f28 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -1298,7 +1298,10 @@ func (i *Image) Comment(ctx context.Context, manifestType string) (string, error if err != nil { return "", err } - return ociv1Img.History[0].Comment, nil + if len(ociv1Img.History) > 0 { + return ociv1Img.History[0].Comment, nil + } + return "", nil } // Save writes a container image to the filesystem diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go index 5ed028b95..b962ffa5c 100644 --- a/pkg/hooks/hooks.go +++ b/pkg/hooks/hooks.go @@ -4,7 +4,6 @@ package hooks import ( "context" "fmt" - "path/filepath" "sort" "strings" "sync" @@ -138,26 +137,3 @@ func (m *Manager) Hooks(config *rspec.Spec, annotations map[string]string, hasBi return extensionStageHooks, nil } - -// remove remove a hook by name. -func (m *Manager) remove(hook string) (ok bool) { - m.lock.Lock() - defer m.lock.Unlock() - _, ok = m.hooks[hook] - if ok { - delete(m.hooks, hook) - } - return ok -} - -// add adds a hook by path -func (m *Manager) add(path string) (err error) { - m.lock.Lock() - defer m.lock.Unlock() - hook, err := Read(path, m.extensionStages) - if err != nil { - return err - } - m.hooks[filepath.Base(path)] = hook - return nil -} diff --git a/pkg/hooks/monitor.go b/pkg/hooks/monitor.go index febe3483f..c50b321f2 100644 --- a/pkg/hooks/monitor.go +++ b/pkg/hooks/monitor.go @@ -2,9 +2,8 @@ package hooks import ( "context" - "os" - "path/filepath" + current "github.com/containers/libpod/pkg/hooks/1.0.0" "github.com/fsnotify/fsnotify" "github.com/sirupsen/logrus" ) @@ -49,47 +48,11 @@ func (m *Manager) Monitor(ctx context.Context, sync chan<- error) { for { select { case event := <-watcher.Events: - filename := filepath.Base(event.Name) - if len(m.directories) <= 1 { - if event.Op&fsnotify.Remove == fsnotify.Remove { - ok := m.remove(filename) - if ok { - logrus.Debugf("removed hook %s", event.Name) - } - } else if event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Write == fsnotify.Write { - err = m.add(event.Name) - if err == nil { - logrus.Debugf("added hook %s", event.Name) - } else if err != ErrNoJSONSuffix { - logrus.Errorf("failed to add hook %s: %v", event.Name, err) - } - } - } else if event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Remove == fsnotify.Remove { - err = nil - found := false - for i := len(m.directories) - 1; i >= 0; i-- { - path := filepath.Join(m.directories[i], filename) - err = m.add(path) - if err == nil { - found = true - logrus.Debugf("(re)added hook %s (triggered activity on %s)", path, event.Name) - break - } else if err == ErrNoJSONSuffix { - found = true - break // this is not going to change for fallback directories - } else if os.IsNotExist(err) { - continue // move on to the next fallback directory - } else { - found = true - logrus.Errorf("failed to (re)add hook %s (triggered by activity on %s): %v", path, event.Name, err) - break - } - } - if (found || event.Op&fsnotify.Remove == fsnotify.Remove) && err != nil { - ok := m.remove(filename) - if ok { - logrus.Debugf("removed hook %s (triggered by activity on %s)", filename, event.Name) - } + m.hooks = make(map[string]*current.Hook) + for _, dir := range m.directories { + err = ReadDir(dir, m.extensionStages, m.hooks) + if err != nil { + logrus.Errorf("failed loading hooks for %s: %v", event.Name, err) } } case <-ctx.Done(): diff --git a/pkg/hooks/monitor_test.go b/pkg/hooks/monitor_test.go index 31d7f9e39..dc67eaf83 100644 --- a/pkg/hooks/monitor_test.go +++ b/pkg/hooks/monitor_test.go @@ -226,7 +226,28 @@ func TestMonitorTwoDirGood(t *testing.T) { assert.Equal(t, primaryInjected, config.Hooks) // masked by primary }) - t.Run("bad-primary-addition", func(t *testing.T) { + primaryPath2 := filepath.Join(primaryDir, "0a.json") //0a because it will be before a.json alphabetically + + t.Run("bad-primary-new-addition", func(t *testing.T) { + err = ioutil.WriteFile(primaryPath2, []byte("{\"version\": \"-1\"}"), 0644) + if err != nil { + t.Fatal(err) + } + + time.Sleep(100 * time.Millisecond) // wait for monitor to notice + + config := &rspec.Spec{} + fmt.Println("expected: ", config.Hooks) + expected := primaryInjected // 0a.json is bad, a.json is still good + _, err = manager.Hooks(config, map[string]string{}, false) + fmt.Println("actual: ", config.Hooks) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, expected, config.Hooks) + }) + + t.Run("bad-primary-same-addition", func(t *testing.T) { err = ioutil.WriteFile(primaryPath, []byte("{\"version\": \"-1\"}"), 0644) if err != nil { t.Fatal(err) @@ -235,7 +256,7 @@ func TestMonitorTwoDirGood(t *testing.T) { time.Sleep(100 * time.Millisecond) // wait for monitor to notice config := &rspec.Spec{} - expected := config.Hooks + expected := fallbackInjected _, err = manager.Hooks(config, map[string]string{}, false) if err != nil { t.Fatal(err) diff --git a/pkg/hooks/read.go b/pkg/hooks/read.go index d3995a0be..560ff1899 100644 --- a/pkg/hooks/read.go +++ b/pkg/hooks/read.go @@ -67,7 +67,7 @@ func ReadDir(path string, extensionStages []string, hooks map[string]*current.Ho if err != nil { return err } - + res := err for _, file := range files { filePath := filepath.Join(path, file.Name()) hook, err := Read(filePath, extensionStages) @@ -80,12 +80,17 @@ func ReadDir(path string, extensionStages []string, hooks map[string]*current.Ho continue } } - return err + if res == nil { + res = err + } else { + res = errors.Wrapf(res, "%v", err) + } + continue } hooks[file.Name()] = hook logrus.Debugf("added hook %s", filePath) } - return nil + return res } func init() { diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index ef1c85518..7e14f9e06 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -214,11 +214,6 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration { cgroupManager = os.Getenv("CGROUP_MANAGER") } - // Ubuntu doesn't use systemd cgroups - if host.Distribution == "ubuntu" { - cgroupManager = "cgroupfs" - } - ociRuntime := os.Getenv("OCI_RUNTIME") if ociRuntime == "" { var err error |