diff options
-rw-r--r-- | .cirrus.yml | 7 | ||||
-rwxr-xr-x | contrib/cirrus/check_image.sh | 4 | ||||
-rw-r--r-- | contrib/cirrus/lib.sh | 9 | ||||
-rwxr-xr-x | contrib/cirrus/setup_environment.sh | 6 | ||||
-rw-r--r-- | libpod/image/pull.go | 2 | ||||
-rw-r--r-- | libpod/runtime.go | 76 | ||||
-rw-r--r-- | pkg/cgroups/cgroups.go | 8 | ||||
-rw-r--r-- | pkg/spec/spec.go | 36 | ||||
-rw-r--r-- | pkg/spec/storage.go | 7 |
9 files changed, 104 insertions, 51 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index da28bb597..e9e843be6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -29,9 +29,9 @@ env: #### #### Cache-image names to test with ### - FEDORA_CACHE_IMAGE_NAME: "fedora-30-libpod-5081463649730560" - PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-29-libpod-5081463649730560" - UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-libpod-5081463649730560" + FEDORA_CACHE_IMAGE_NAME: "fedora-30-libpod-5744029755506688" + PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-29-libpod-5744029755506688" + UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-libpod-5744029755506688" #### #### Variables for composing new cache-images (used in PR testing) from @@ -472,6 +472,7 @@ verify_test_built_images_task: environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}' check_image_script: '$SCRIPT_BASE/check_image.sh' integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}' + system_test_script: '$SCRIPT_BASE/system_test.sh |& ${TIMESTAMP}' always: <<: *standardlogs diff --git a/contrib/cirrus/check_image.sh b/contrib/cirrus/check_image.sh index 948039234..67e807d61 100755 --- a/contrib/cirrus/check_image.sh +++ b/contrib/cirrus/check_image.sh @@ -16,7 +16,9 @@ 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 "podman command NOT found on path" -z "$(type -P podman)" || let "RET+=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" MIN_ZIP_VER='3.0' VER_RE='.+([[:digit:]]+\.[[:digit:]]+).+' diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index ea0f9e326..b2fcaa749 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -323,8 +323,15 @@ install_test_configs(){ /etc/containers/registries.conf } +# Remove all files (except conmon, for now) provided by the distro version of podman. +# Except conmon, for now as it's expected to eventually be packaged separately. +# All VM cache-images used for testing include the distro podman because (1) it's +# required for podman-in-podman testing and (2) it somewhat simplifies the task +# of pulling in necessary prerequisites packages as the set can change over time. +# For general CI testing however, calling this function makes sure the system +# can only run the compiled source version. remove_packaged_podman_files(){ - show_and_store_warning "Removing packaged podman files to prevent conflicts with source build and testing." + echo "Removing packaged podman files to prevent conflicts with source build and testing." req_env_var OS_RELEASE_ID if [[ "$OS_RELEASE_ID" =~ "ubuntu" ]] then diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index f312e593a..e49bb98fe 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -52,7 +52,9 @@ install_test_configs make install.tools case "$SPECIALMODE" in - none) ;; # Do the normal thing + none) + remove_packaged_podman_files # we're building from source + ;; rootless) # Only do this once, even if ROOTLESS_USER (somehow) changes if ! grep -q 'ROOTLESS_USER' /etc/environment @@ -65,9 +67,9 @@ case "$SPECIALMODE" in tee -a /etc/environment) && eval "$X" && echo "$X" setup_rootless fi + remove_packaged_podman_files ;; in_podman) # Assumed to be Fedora - dnf install -y podman $SCRIPT_BASE/setup_container_environment.sh ;; windows) ;& # for podman-remote building only diff --git a/libpod/image/pull.go b/libpod/image/pull.go index 581beb538..2f1d1e912 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -267,7 +267,7 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa copyOptions.SourceCtx.SystemRegistriesConfPath = systemRegistriesConfPath // FIXME: Set this more globally. Probably no reason not to have it in every types.SystemContext, and to compute the value just once in one place. // Print the following statement only when pulling from a docker or atomic registry if writer != nil && (imageInfo.srcRef.Transport().Name() == DockerTransport || imageInfo.srcRef.Transport().Name() == AtomicTransport) { - if _, err := io.WriteString(writer, fmt.Sprintf("Trying to pull %s...", imageInfo.image)); err != nil { + if _, err := io.WriteString(writer, fmt.Sprintf("Trying to pull %s...\n", imageInfo.image)); err != nil { return nil, err } } diff --git a/libpod/runtime.go b/libpod/runtime.go index 9196547a2..08c6cb588 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -854,39 +854,20 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { } else if runtime.noStore { logrus.Debug("No store required. Not opening container store.") } else { - store, err = storage.GetStore(runtime.config.StorageConfig) - if err != nil { + if err := runtime.configureStore(); err != nil { return err } - err = nil - - defer func() { - if err != nil && store != nil { - // Don't forcibly shut down - // We could be opening a store in use by another libpod - _, err2 := store.Shutdown(false) - if err2 != nil { - logrus.Errorf("Error removing store for partially-created runtime: %s", err2) - } - } - }() } - - runtime.store = store - is.Transport.SetStore(store) - - // Set up image runtime and store in runtime - ir := image.NewImageRuntimeFromStore(runtime.store) - - runtime.imageRuntime = ir - - // Setting signaturepolicypath - ir.SignaturePolicyPath = runtime.config.SignaturePolicyPath - - // Set logfile path for events - ir.EventsLogFilePath = runtime.config.EventsLogFilePath - // Set logger type - ir.EventsLogger = runtime.config.EventsLogger + defer func() { + if err != nil && store != nil { + // Don't forcibly shut down + // We could be opening a store in use by another libpod + _, err2 := store.Shutdown(false) + if err2 != nil { + logrus.Errorf("Error removing store for partially-created runtime: %s", err2) + } + } + }() // Setup the eventer eventer, err := runtime.newEventer() @@ -894,7 +875,9 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { return err } runtime.eventer = eventer - ir.Eventer = eventer + if runtime.imageRuntime != nil { + runtime.imageRuntime.Eventer = eventer + } // Set up a storage service for creating container root filesystems from // images @@ -1125,6 +1108,13 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { // If we need to refresh the state, do it now - things are guaranteed to // be set up by now. if doRefresh { + // Ensure we have a store before refresh occurs + if runtime.store == nil { + if err := runtime.configureStore(); err != nil { + return err + } + } + if err2 := runtime.refresh(runtimeAliveFile); err2 != nil { return err2 } @@ -1330,7 +1320,29 @@ func (r *Runtime) generateName() (string, error) { // The code should never reach here. } -// ImageRuntime returns the imageruntime for image resolution +// Configure store and image runtime +func (r *Runtime) configureStore() error { + store, err := storage.GetStore(r.config.StorageConfig) + if err != nil { + return err + } + + r.store = store + is.Transport.SetStore(store) + + ir := image.NewImageRuntimeFromStore(r.store) + ir.SignaturePolicyPath = r.config.SignaturePolicyPath + ir.EventsLogFilePath = r.config.EventsLogFilePath + ir.EventsLogger = r.config.EventsLogger + + r.imageRuntime = ir + + return nil +} + +// ImageRuntime returns the imageruntime for image operations. +// If WithNoStore() was used, no image runtime will be available, and this +// function will return nil. func (r *Runtime) ImageRuntime() *image.Runtime { return r.imageRuntime } diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index 081db772f..fda19bff8 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -187,8 +187,12 @@ func createCgroupv2Path(path string) (Err error) { }() } } - if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), resByte, 0755); err != nil { - return errors.Wrapf(err, "write %s", filepath.Join(current, "cgroup.subtree_control")) + // We enable the controllers for all the path components except the last one. It is not allowed to add + // PIDs if there are already enabled controllers. + if i < len(elements[3:])-1 { + if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), resByte, 0755); err != nil { + return errors.Wrapf(err, "write %s", filepath.Join(current, "cgroup.subtree_control")) + } } } return nil diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index d44beb3e4..53b73296a 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -86,23 +86,41 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM g.AddLinuxMaskedPaths("/sys/kernel") } } + gid5Available := true if isRootless { nGids, err := getAvailableGids() if err != nil { return nil, err } - if nGids < 5 { - // If we have no GID mappings, the gid=5 default option would fail, so drop it. - g.RemoveMount("/dev/pts") - devPts := spec.Mount{ - Destination: "/dev/pts", - Type: "devpts", - Source: "devpts", - Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"}, + gid5Available = nGids >= 5 + } + // When using a different user namespace, check that the GID 5 is mapped inside + // the container. + if gid5Available && len(config.IDMappings.GIDMap) > 0 { + mappingFound := false + for _, r := range config.IDMappings.GIDMap { + if r.ContainerID <= 5 && 5 < r.ContainerID+r.Size { + mappingFound = true + break } - g.AddMount(devPts) } + if !mappingFound { + gid5Available = false + } + } + if !gid5Available { + // If we have no GID mappings, the gid=5 default option would fail, so drop it. + g.RemoveMount("/dev/pts") + devPts := spec.Mount{ + Destination: "/dev/pts", + Type: "devpts", + Source: "devpts", + Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"}, + } + g.AddMount(devPts) + } + if inUserNS && config.IpcMode.IsHost() { g.RemoveMount("/dev/mqueue") devMqueue := spec.Mount{ diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go index ed767f5ba..88f1f6dc1 100644 --- a/pkg/spec/storage.go +++ b/pkg/spec/storage.go @@ -211,6 +211,13 @@ func (config *CreateConfig) parseVolumes(runtime *libpod.Runtime) ([]spec.Mount, } mount.Options = opts } + if mount.Type == TypeBind { + absSrc, err := filepath.Abs(mount.Source) + if err != nil { + return nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source) + } + mount.Source = absSrc + } finalMounts = append(finalMounts, mount) } finalVolumes := make([]*libpod.ContainerNamedVolume, 0, len(baseVolumes)) |