diff options
-rw-r--r-- | .cirrus.yml | 15 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | cmd/podman/main.go | 20 | ||||
-rwxr-xr-x | contrib/cirrus/build_release.sh | 24 | ||||
-rw-r--r-- | contrib/cirrus/packer/fedora_setup.sh | 3 | ||||
-rwxr-xr-x | contrib/cirrus/upload_release_archive.sh | 62 | ||||
-rw-r--r-- | contrib/perftest/main.go | 7 | ||||
-rwxr-xr-x | contrib/upldrel/entrypoint.sh | 57 | ||||
-rw-r--r-- | docs/tutorials/README.md | 10 | ||||
-rwxr-xr-x | hack/get_release_info.sh | 2 | ||||
-rw-r--r-- | libpod/image/image.go | 4 | ||||
-rw-r--r-- | libpod/image/image_test.go | 8 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.go | 2 | ||||
-rw-r--r-- | test/e2e/common_test.go | 10 | ||||
-rw-r--r-- | test/e2e/start_test.go | 17 | ||||
-rw-r--r-- | test/utils/utils.go | 2 |
16 files changed, 144 insertions, 102 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index d128337c3..1665f3d9c 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -351,8 +351,14 @@ testing_task: integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}' system_test_script: '$SCRIPT_BASE/system_test.sh |& ${TIMESTAMP}' build_release_script: '$SCRIPT_BASE/build_release.sh |& ${TIMESTAMP}' + # For PRs this confirms uploading releases after merge, is functional. upload_release_archive_script: '$SCRIPT_BASE/upload_release_archive.sh |& ${TIMESTAMP}' + # When examining a particular run, provide convenient access to release files. + tar_artifacts: + path: "*.tar.gz" + type: "application/x-tar" + on_failure: failed_branch_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_branch_failure.sh' @@ -480,6 +486,15 @@ special_testing_cross_task: on_failure: failed_branch_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_branch_failure.sh' + # When examining a particular run, provide convenient access to release files. + zip_artifacts: + path: "*.zip" + type: "application/zip" + + msi_artifacts: + path: "*.msi" + type: "application/octet-stream" + special_testing_cgroupv2_task: @@ -35,6 +35,9 @@ This project tests all builds against each supported version of Fedora, the late ## Communications +If you think you've identified a security issue in the project, please *DO NOT* report the issue publically via the Github issue tracker, mailing list, or IRC. +Instead, send an email with as many details as possible to `security@lists.podman.io`. This is a private mailing list for the core maintainers. + For general questions and discussion, please use the IRC `#podman` channel on `irc.freenode.net`. diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 992dbe1d5..344170ddd 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -107,15 +107,6 @@ func before(cmd *cobra.Command, args []string) error { os.Exit(1) } - if err := setupRootless(cmd, args); err != nil { - return err - } - - // check that global opts input is valid - if err := checkInput(); err != nil { - return err - } - // Set log level; if not log-level is provided, default to error logLevel := MainGlobalOpts.LogLevel if logLevel == "" { @@ -130,6 +121,15 @@ func before(cmd *cobra.Command, args []string) error { return err } + if err := setupRootless(cmd, args); err != nil { + return err + } + + // check that global opts input is valid + if err := checkInput(); err != nil { + return err + } + if err := setRLimits(); err != nil { return err } @@ -149,6 +149,8 @@ func main() { //cpuProfile := false if reexec.Init() { + // We were invoked with a different argv[0] indicating that we + // had a specific job to do as a subprocess, and it's done. return } // Hard code TMPDIR functions to use /var/tmp, if user did not override diff --git a/contrib/cirrus/build_release.sh b/contrib/cirrus/build_release.sh index 287643f47..07db88f81 100755 --- a/contrib/cirrus/build_release.sh +++ b/contrib/cirrus/build_release.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + source $(dirname $0)/lib.sh req_env_var TEST_REMOTE_CLIENT OS_RELEASE_ID GOSRC @@ -13,18 +15,20 @@ fi if [[ -n "$CROSS_PLATFORM" ]] then + # Will fail if $CROSS_PLATFORM is unsupported cross-compile $GOOS value + make podman-remote-${CROSS_PLATFORM}-release + echo "Compiling podman-remote release archive for ${CROSS_PLATFORM}" - case "$CROSS_PLATFORM" in - linux) ;& - windows) ;& - darwin) - make podman-remote-${CROSS_PLATFORM}-release - ;; - *) - die 1 "Unknown/unsupported cross-compile platform '$CROSS_PLATFORM'" - ;; - esac + if [[ "$CROSS_PLATFORM" == "windows" ]] + then + # TODO: Remove next line, part of VM images next time they're built. + dnf install -y libmsi1 msitools pandoc + make podman.msi + fi else echo "Compiling release archive for $OS_RELEASE_ID" make podman-release fi + +echo "Preserving build details for later use." +mv -v release.txt actual_release.txt # Another 'make' during testing could overwrite it diff --git a/contrib/cirrus/packer/fedora_setup.sh b/contrib/cirrus/packer/fedora_setup.sh index 6709eecaf..f84645a04 100644 --- a/contrib/cirrus/packer/fedora_setup.sh +++ b/contrib/cirrus/packer/fedora_setup.sh @@ -53,6 +53,7 @@ ooe.sh sudo dnf install -y \ jq \ libassuan-devel \ libcap-devel \ + libmsi1 \ libnet \ libnet-devel \ libnl3-devel \ @@ -62,9 +63,11 @@ ooe.sh sudo dnf install -y \ libvarlink-util \ lsof \ make \ + msitools \ nmap-ncat \ ostree \ ostree-devel \ + pandoc \ podman \ procps-ng \ protobuf \ diff --git a/contrib/cirrus/upload_release_archive.sh b/contrib/cirrus/upload_release_archive.sh index 942255821..25107f0ef 100755 --- a/contrib/cirrus/upload_release_archive.sh +++ b/contrib/cirrus/upload_release_archive.sh @@ -9,6 +9,7 @@ req_env_var CI UPLDREL_IMAGE CIRRUS_BUILD_ID GOSRC RELEASE_GCPJSON RELEASE_GCPNA [[ "$CI" == "true" ]] || \ die 56 "$0 must be run under Cirrus-CI to function" +# We store "releases" for each PR, mostly to validate the process is functional unset PR_OR_BRANCH BUCKET if [[ -n "$CIRRUS_PR" ]] then @@ -22,31 +23,76 @@ else die 1 "Expecting either \$CIRRUS_PR or \$CIRRUS_BRANCH to be non-empty." fi -# Functional local podman required for uploading a release +echo "Parsing actual_release.txt contents: $(< actual_release.txt)" cd $GOSRC +RELEASETXT=$(<actual_release.txt) # see build_release.sh +[[ -n "$RELEASETXT" ]] || \ + die 3 "Could not obtain metadata from actual_release.txt" +RELEASE_INFO=$(echo "$RELEASETXT" | grep -m 1 'X-RELEASE-INFO:' | sed -r -e 's/X-RELEASE-INFO:\s*(.+)/\1/') +if [[ "$?" -ne "0" ]] || [[ -z "$RELEASE_INFO" ]] +then + die 4 "Metadata is empty or invalid: '$RELEASETXT'" +fi +# Format specified in Makefile +# e.g. libpod v1.3.1-166-g60df124e fedora 29 amd64 +# or libpod-remote v1.3.1-166-g60df124e windows - amd64 +FIELDS="RELEASE_BASENAME RELEASE_VERSION RELEASE_DIST RELEASE_DIST_VER RELEASE_ARCH" +read $FIELDS <<< $RELEASE_INFO +req_env_var $FIELDS + +# Functional local podman required for uploading +echo "Verifying a local, functional podman, building one if necessary." [[ -n "$(type -P podman)" ]] || \ - make install || \ + make install PREFIX=/usr || \ die 57 "$0 requires working podman binary on path to function" TMPF=$(mktemp -p '' $(basename $0)_XXXX.json) trap "rm -f $TMPF" EXIT set +x echo "$RELEASE_GCPJSON" > "$TMPF" +[[ "$OS_RELEASE_ID" == "ubuntu" ]] || \ + chcon -t container_file_t "$TMPF" unset RELEASE_GCPJSON cd $GOSRC -for filename in $(ls -1 *.tar.gz *.zip) +for filename in $(ls -1 *.tar.gz *.zip *.msi) do - echo "Running podman ... $UPLDREL_IMAGE $filename" + unset EXT + EXT=$(echo "$filename" | sed -r -e 's/.+\.(.+$)/\1/g') + if [[ -z "$EXT" ]] || [[ "$EXT" == "$filename" ]] + then + echo "Warning: Not processing $filename (invalid extension '$EXT')" + continue + fi + + [[ "$OS_RELEASE_ID" == "ubuntu" ]] || \ + chcon -t container_file_t "$filename" + # Form the generic "latest" file for this branch or pr + TO_PREFIX="${RELEASE_BASENAME}-latest-${PR_OR_BRANCH}-${RELEASE_DIST}" + # Form the fully-versioned filename for historical sake + ALSO_PREFIX="${RELEASE_BASENAME}-${RELEASE_VERSION}-${PR_OR_BRANCH}-${RELEASE_DIST}" + TO_SUFFIX="${RELEASE_ARCH}.${EXT}" + if [[ "$RELEASE_DIST" == "windows" ]] || [[ "$RELEASE_DIST" == "darwin" ]] + then + TO_FILENAME="${TO_PREFIX}-${TO_SUFFIX}" + ALSO_FILENAME="${ALSO_PREFIX}-${TO_SUFFIX}" + else + TO_FILENAME="${TO_PREFIX}-${RELEASE_DIST_VER}-${TO_SUFFIX}" + ALSO_FILENAME="${ALSO_PREFIX}-${TO_SUFFIX}" + fi + + echo "Running podman ... $UPLDREL_IMAGE for $filename -> $TO_FILENAME" + echo "Warning: upload failures are completely ignored, avoiding any needless holdup of PRs." podman run -i --rm \ -e "GCPNAME=$RELEASE_GCPNAME" \ -e "GCPPROJECT=$RELEASE_GCPROJECT" \ -e "GCPJSON_FILEPATH=$TMPF" \ - -e "REL_ARC_FILEPATH=/tmp/$filename" \ + -e "FROM_FILEPATH=/tmp/$filename" \ + -e "TO_FILENAME=$TO_FILENAME" \ + -e "ALSO_FILENAME=$ALSO_FILENAME" \ -e "PR_OR_BRANCH=$PR_OR_BRANCH" \ -e "BUCKET=$BUCKET" \ - --security-opt label=disable \ -v "$TMPF:$TMPF:ro" \ - -v "$GOSRC/$filename:/tmp/$filename:ro" \ - $UPLDREL_IMAGE + -v "$(realpath $GOSRC/$filename):/tmp/$filename:ro" \ + $UPLDREL_IMAGE || true done diff --git a/contrib/perftest/main.go b/contrib/perftest/main.go index f6c90914a..9b928a6b3 100644 --- a/contrib/perftest/main.go +++ b/contrib/perftest/main.go @@ -36,6 +36,9 @@ var helpMessage = ` ` func main() { + if reexec.Init() { + return + } ctx := context.Background() imageName := "" @@ -51,10 +54,6 @@ func main() { flag.Parse() - if reexec.Init() { - return - } - switch strings.ToLower(*logLevel) { case "error": logrus.SetLevel(logrus.ErrorLevel) diff --git a/contrib/upldrel/entrypoint.sh b/contrib/upldrel/entrypoint.sh index 985b828a0..6af6829c5 100755 --- a/contrib/upldrel/entrypoint.sh +++ b/contrib/upldrel/entrypoint.sh @@ -4,59 +4,22 @@ set -e source /usr/local/bin/lib_entrypoint.sh -req_env_var GCPJSON_FILEPATH GCPNAME GCPPROJECT REL_ARC_FILEPATH PR_OR_BRANCH BUCKET +req_env_var GCPJSON_FILEPATH GCPNAME GCPPROJECT BUCKET FROM_FILEPATH TO_FILENAME ALSO_FILENAME -[[ -r "$REL_ARC_FILEPATH" ]] || \ +[[ -r "$FROM_FILEPATH" ]] || \ die 2 ERROR Cannot read release archive file: "$REL_ARC_FILEPATH" [[ -r "$GCPJSON_FILEPATH" ]] || \ die 3 ERROR Cannot read GCP credentials file: "$GCPJSON_FILEPATH" -cd $TMPDIR -echo "Attempting to extract release.txt from tar or zip $REL_ARC_FILEPATH" -unset SFX -if tar xzf "$REL_ARC_FILEPATH" "./release.txt" -then - echo "It's a tarball" - SFX="tar.gz" -elif unzip "$REL_ARC_FILEPATH" release.txt -then - echo "It's a zip" - SFX="zip" -else - die 5 ERROR Could not extract release.txt from $REL_ARC_FILEPATH -fi - -echo "Parsing release.txt contents" -RELEASETXT=$(<release.txt) -cd - -[[ -n "$RELEASETXT" ]] || \ - die 3 ERROR Could not obtain metadata from release.txt in $REL_ARC_FILEPATH - -RELEASE_INFO=$(echo "$RELEASETXT" | grep -m 1 'X-RELEASE-INFO:' | sed -r -e 's/X-RELEASE-INFO:\s*(.+)/\1/') -if [[ "$?" -ne "0" ]] || [[ -z "$RELEASE_INFO" ]] -then - die 4 ERROR Metadata is empty or invalid: '$RELEASETXT' -fi - -# e.g. libpod v1.3.1-166-g60df124e fedora 29 amd64 -# or libpod v1.3.1-166-g60df124e amd64 -FIELDS="RELEASE_BASENAME RELEASE_VERSION RELEASE_DIST RELEASE_DIST_VER RELEASE_ARCH" -read $FIELDS <<< $RELEASE_INFO -for f in $FIELDS -do - [[ -n "${!f}" ]] || \ - die 5 ERROR Expecting $f to be non-empty in metadata: '$RELEASE_INFO' -done - +echo "Authenticating to google cloud for upload" gcloud_init "$GCPJSON_FILEPATH" -# Drop version number to enable "latest" representation -# (version available w/in zip-file comment) -RELEASE_ARCHIVE_NAME="${RELEASE_BASENAME}-${PR_OR_BRANCH}-${RELEASE_DIST}-${RELEASE_DIST_VER}-${RELEASE_ARCH}.${SFX}" - -echo "Uploading archive as $RELEASE_ARCHIVE_NAME" -gsutil cp "$REL_ARC_FILEPATH" "gs://$BUCKET/$RELEASE_ARCHIVE_NAME" +echo "Uploading archive as $TO_FILENAME" +gsutil cp "$FROM_FILEPATH" "gs://$BUCKET/$TO_FILENAME" +gsutil cp "$FROM_FILEPATH" "gs://$BUCKET/$ALSO_FILENAME" -echo "Release now available at:" -echo " https://storage.cloud.google.com/$BUCKET/$RELEASE_ARCHIVE_NAME" +echo "." +echo "Release now available for download at:" +echo " https://storage.cloud.google.com/$BUCKET/$TO_FILENAME" +echo " https://storage.cloud.google.com/$BUCKET/$ALSO_FILENAME" diff --git a/docs/tutorials/README.md b/docs/tutorials/README.md index c340d683f..2cf9613b6 100644 --- a/docs/tutorials/README.md +++ b/docs/tutorials/README.md @@ -4,18 +4,18 @@ ## Links to a number of useful tutorials for the Podman utility. -**[Introduction Tutorial](https://github.com/containers/libpod/tree/master/docs/tutorials/podman_tutorial.md)** +**[Introduction Tutorial](podman_tutorial.md)** Learn how to setup Podman and perform some basic commands with the utility. -**[Basic Setup and Use of Podman in a Rootless environment.](https://github.com/containers/libpod/blob/master/docs/tutorials/rootless_tutorial.md).** +**[Basic Setup and Use of Podman in a Rootless environment](rootless_tutorial.md)** The steps required to setup rootless Podman are enumerated. -**[Setup on OS X](https://github.com/containers/libpod/blob/master/doc/tutorials/mac_client.md)** +**[Setup on OS X](mac_client.md)** -Special setup for running the Podman remote client on a Mac and connecting to Podman running on a Linux VM are documented +Special setup for running the Podman remote client on a Mac and connecting to Podman running on a Linux VM are documented. -**[Remote Client](https://github.com/containers/libpod/blob/master/doc/tutorials/remote_client.md)** +**[Remote Client](remote_client.md)** A brief how-to on using the Podman remote-client. diff --git a/hack/get_release_info.sh b/hack/get_release_info.sh index 29b4237b4..b75751170 100755 --- a/hack/get_release_info.sh +++ b/hack/get_release_info.sh @@ -33,7 +33,7 @@ case "$1" in OUTPUT="${GOARCH:-$(go env GOARCH 2> /dev/null)}" ;; BASENAME*) - OUTPUT="${CIRRUS_REPO_NAME:-$(basename $(git rev-parse --show-toplevel))}" + OUTPUT="podman" ;; REMOTENAME*) OUTPUT="$($0 BASENAME)-remote" diff --git a/libpod/image/image.go b/libpod/image/image.go index 0be6eeeb9..855da8611 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -29,7 +29,6 @@ import ( "github.com/containers/libpod/pkg/registries" "github.com/containers/libpod/pkg/util" "github.com/containers/storage" - "github.com/containers/storage/pkg/reexec" "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" @@ -85,9 +84,6 @@ func NewImageRuntimeFromStore(store storage.Store) *Runtime { // NewImageRuntimeFromOptions creates an Image Runtime including the store given // store options func NewImageRuntimeFromOptions(options storage.StoreOptions) (*Runtime, error) { - if reexec.Init() { - return nil, errors.Errorf("unable to reexec") - } store, err := setStore(options) if err != nil { return nil, err diff --git a/libpod/image/image_test.go b/libpod/image/image_test.go index 5a6d095f6..ef39d09c3 100644 --- a/libpod/image/image_test.go +++ b/libpod/image/image_test.go @@ -11,6 +11,7 @@ import ( "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/pkg/util" "github.com/containers/storage" + "github.com/containers/storage/pkg/reexec" "github.com/opencontainers/go-digest" "github.com/stretchr/testify/assert" ) @@ -70,6 +71,13 @@ func makeLocalMatrix(b, bg *Image) ([]localImageTest, error) { } +func TestMain(m *testing.M) { + if reexec.Init() { + return + } + os.Exit(m.Run()) +} + // TestImage_NewFromLocal tests finding the image locally by various names, // tags, and aliases func TestImage_NewFromLocal(t *testing.T) { diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index ecb84f6a9..6f6239e5f 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -365,7 +365,7 @@ func GetConfiguredMappings() ([]idtools.IDMap, []idtools.IDMap, error) { } mappings, err := idtools.NewIDMappings(username, username) if err != nil { - logrus.Warnf("cannot find mappings for user %s: %v", username, err) + logrus.Errorf("cannot find mappings for user %s: %v", username, err) } else { uids = mappings.UIDs() gids = mappings.GIDs() diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 4e9881d59..1c2acf8ed 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -78,11 +78,15 @@ func (a testResultsSorted) Less(i, j int) bool { return a[i].length < a[j].lengt var testResults []testResult -// TestLibpod ginkgo master function -func TestLibpod(t *testing.T) { +func TestMain(m *testing.M) { if reexec.Init() { - os.Exit(1) + return } + os.Exit(m.Run()) +} + +// TestLibpod ginkgo master function +func TestLibpod(t *testing.T) { if os.Getenv("NOCACHE") == "1" { CACHE_IMAGES = []string{} RESTORE_IMAGES = []string{} diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index fc1203ed1..06ab6aacd 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -6,6 +6,7 @@ import ( . "github.com/containers/libpod/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman start", func() { @@ -107,32 +108,30 @@ var _ = Describe("Podman start", func() { start := podmanTest.Podman([]string{"start", "-l"}) start.WaitWithDefaultTimeout() - Expect(start.ExitCode()).To(Not(Equal(0))) + Expect(start.ExitCode()).Should(BeNumerically(">", 0)) - numContainers := podmanTest.NumberOfContainers() - Expect(numContainers).To(BeZero()) + Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout).Should(BeZero()) }) It("podman failed to start without --rm should NOT delete the container", func() { session := podmanTest.Podman([]string{"create", "-it", ALPINE, "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) start := podmanTest.Podman([]string{"start", "-l"}) start.WaitWithDefaultTimeout() - Expect(start.ExitCode()).To(Not(Equal(0))) + Expect(start.ExitCode()).Should(BeNumerically(">", 0)) - numContainers := podmanTest.NumberOfContainers() - Expect(numContainers).To(Equal(1)) + Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout).Should(Equal(1)) }) It("podman start --sig-proxy should not work without --attach", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"start", "-l", "--sig-proxy"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session).Should(Exit(125)) }) }) diff --git a/test/utils/utils.go b/test/utils/utils.go index 028107d46..2ae140fab 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -320,7 +320,7 @@ func (s *PodmanSession) IsJSONOutputValid() bool { // WaitWithDefaultTimeout waits for process finished with defaultWaitTimeout func (s *PodmanSession) WaitWithDefaultTimeout() { - s.Wait(defaultWaitTimeout) + Eventually(s, defaultWaitTimeout).Should(gexec.Exit()) os.Stdout.Sync() os.Stderr.Sync() fmt.Println("output:", s.OutputToString()) |