diff options
-rw-r--r-- | .cirrus.yml | 20 | ||||
-rw-r--r-- | .papr.yml | 80 | ||||
-rwxr-xr-x | API.md | 19 | ||||
-rw-r--r-- | cmd/podman/images.go | 6 | ||||
-rw-r--r-- | cmd/podman/pod_create.go | 38 | ||||
-rw-r--r-- | cmd/podman/rmi.go | 25 | ||||
-rw-r--r-- | cmd/podman/shared/pod.go | 37 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 14 | ||||
-rw-r--r-- | contrib/cirrus/lib.sh | 13 | ||||
-rw-r--r-- | contrib/cirrus/packer/fedora_setup.sh | 1 | ||||
-rw-r--r-- | contrib/cirrus/packer/libpod_base_images.yml | 18 | ||||
-rw-r--r-- | contrib/cirrus/packer/libpod_images.yml | 5 | ||||
l--------- | contrib/cirrus/packer/prior_fedora_base-setup.sh | 1 | ||||
-rwxr-xr-x | contrib/cirrus/setup_environment.sh | 7 | ||||
-rwxr-xr-x | contrib/cirrus/unit_test.sh | 1 | ||||
-rwxr-xr-x | hack/get_ci_vm.sh | 85 | ||||
-rw-r--r-- | pkg/varlinkapi/images.go | 93 | ||||
-rw-r--r-- | pkg/varlinkapi/pods.go | 20 | ||||
-rw-r--r-- | test/README.md | 2 | ||||
-rw-r--r-- | test/e2e/checkpoint_test.go | 6 | ||||
-rw-r--r-- | test/e2e/images_test.go | 4 | ||||
-rw-r--r-- | test/e2e/libpod_suite_test.go | 2 |
22 files changed, 350 insertions, 147 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 09f13a7d0..9d64bb5ab 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -34,14 +34,15 @@ env: CRIU_COMMIT: "c74b83cd49c00589c0c0468ba5fe685b67fdbd0a" RUNC_COMMIT: "25f3f893c86d07426df93b7aa172f33fdf093fbd" # CSV of cache-image names to build (see $PACKER_BASE/libpod_images.json) - PACKER_BUILDS: "ubuntu-18,fedora-29" # TODO: fah-29,rhel-7,centos-7 + PACKER_BUILDS: "ubuntu-18,fedora-29,fedora-28" # TODO: fah-29,rhel-7,centos-7 # Version of packer to use PACKER_VER: "1.3.1" # Google-maintained base-image names UBUNTU_BASE_IMAGE: "ubuntu-1804-bionic-v20181203a" CENTOS_BASE_IMAGE: "centos-7-v20181113" # Manually produced base-image names (see $SCRIPT_BASE/README.md) - FEDORA_BASE_IMAGE: "fedora-cloud-base-29-1-2-1541789245" + FEDORA_BASE_IMAGE: "fedora-cloud-base-29-1-2-1541789245" + PRIOR_FEDORA_BASE_IMAGE: "fedora-cloud-base-28-1-1-1544474897" FAH_BASE_IMAGE: "fedora-atomichost-29-20181025-1-1541787861" # RHEL image must be imported, google bills extra for their native image. RHEL_BASE_IMAGE: "rhel-guest-image-7-6-210-x86-64-qcow2-1541783972" @@ -106,13 +107,15 @@ testing_task: zone: "us-central1-a" # Required by Cirrus for the time being cpu: 2 memory: "4Gb" - disk: 40 + disk: 200 # see https://developers.google.com/compute/docs/disks#performance # Generate multiple parallel tasks, covering all possible # 'matrix' combinations. matrix: # Images are generated separately, from build_images_task (below) - image_name: "ubuntu-18-libpod-0c954a67" - image_name: "fedora-29-libpod-0c954a67" + image_name: "ubuntu-18-libpod-86d821ea" + image_name: "fedora-28-libpod-86d821ea" + image_name: "fedora-29-libpod-86d821ea" + # TODO: tests fail # image_name: "rhel-7-something-something" # image_name: "centos-7-something-something" @@ -148,8 +151,9 @@ optional_testing_task: gce_instance: image_project: "libpod-218412" matrix: - image_name: "ubuntu-18-libpod-0c954a67" - image_name: "fedora-29-libpod-0c954a67" + image_name: "ubuntu-18-libpod-86d821ea" + image_name: "fedora-28-libpod-86d821ea" + image_name: "fedora-29-libpod-86d821ea" # TODO: Make these work (also build_images_task below) #image_name: "rhel-server-ec2-7-5-165-1-libpod-fce09afe" #image_name: "centos-7-v20180911-libpod-fce09afe" @@ -185,7 +189,7 @@ cache_images_task: zone: "us-central1-a" # Required by Cirrus for the time being cpu: 4 memory: "4Gb" - disk: 20 + disk: 200 image_name: "image-builder-image-1541772081" # Simply CentOS 7 + packer dependencies # Additional permissions for building GCE images, within a GCE VM scopes: @@ -22,33 +22,33 @@ 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 +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 - timeout: 90m +required: true - tests: - - CONTAINER_RUNTIME="docker" sh .papr_prepare.sh +timeout: 90m - artifacts: - - build.log +tests: + - CONTAINER_RUNTIME="docker" sh .papr_prepare.sh - context: "CAH 7-smoketested - Containerized (Podman in Docker)" +artifacts: + - build.log ---- +context: "CAH 7-smoketested - Containerized (Podman in Docker)" +#--- +# #host: # distro: centos/7/cloud # specs: @@ -95,41 +95,3 @@ context: "FAH28 - Containerized (Podman in Podman)" #context: "CentOS 7 Cloud" # #--- - -host: - distro: fedora/28/cloud - specs: - ram: 8192 - cpus: 4 -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 - - python3-varlink - - python3-dateutil - - python3-psutil - - https://kojipkgs.fedoraproject.org//packages/runc/1.0.0/54.dev.git00dc700.fc28/x86_64/runc-1.0.0-54.dev.git00dc700.fc28.x86_64.rpm - -tests: - - sed 's/^expand-check.*/expand-check=0/g' -i /etc/selinux/semanage.conf - - yum -y reinstall container-selinux - - sh .papr.sh -b -i -t -p - -required: false - -timeout: 90m -context: "Fedora 28 Cloud" @@ -87,9 +87,9 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func Ping() StringResponse](#Ping) -[func PullImage(name: string) string](#PullImage) +[func PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: bool) string](#PullImage) -[func PushImage(name: string, tag: string, tlsverify: bool) string](#PushImage) +[func PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) string](#PushImage) [func RemoveContainer(name: string, force: bool) string](#RemoveContainer) @@ -739,7 +739,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.Ping ### <a name="PullImage"></a>func PullImage <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method PullImage(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div> +method PullImage(name: [string](https://godoc.org/builtin#string), certDir: [string](https://godoc.org/builtin#string), creds: [string](https://godoc.org/builtin#string), signaturePolicy: [string](https://godoc.org/builtin#string), tlsVerify: [bool](https://godoc.org/builtin#bool)) [string](https://godoc.org/builtin#string)</div> PullImage pulls an image from a repository to local storage. After the pull is successful, the ID of the image is returned. #### Example @@ -752,7 +752,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.PullImage '{"name": "regi ### <a name="PushImage"></a>func PushImage <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method PushImage(name: [string](https://godoc.org/builtin#string), tag: [string](https://godoc.org/builtin#string), tlsverify: [bool](https://godoc.org/builtin#bool)) [string](https://godoc.org/builtin#string)</div> +method PushImage(name: [string](https://godoc.org/builtin#string), tag: [string](https://godoc.org/builtin#string), tlsverify: [bool](https://godoc.org/builtin#bool), signaturePolicy: [string](https://godoc.org/builtin#string), creds: [string](https://godoc.org/builtin#string), certDir: [string](https://godoc.org/builtin#string), compress: [bool](https://godoc.org/builtin#bool), format: [string](https://godoc.org/builtin#string), removeSignatures: [bool](https://godoc.org/builtin#bool), signBy: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div> PushImage takes three input arguments: the name or ID of an image, the fully-qualified destination name of the image, and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior). It will return an [ImageNotFound](#ImageNotFound) error if @@ -1499,9 +1499,8 @@ reason [string](https://godoc.org/builtin#string) ### <a name="PodCreate"></a>type PodCreate PodCreate is an input structure for creating pods. -It emulates options to podman pod create, however -changing pause image name and pause container -is not currently supported +It emulates options to podman pod create. The infraCommand and +infraImage options are currently NotSupported. name [string](https://godoc.org/builtin#string) @@ -1512,6 +1511,12 @@ labels [map[string]](#map[string]) share [[]string](#[]string) infra [bool](https://godoc.org/builtin#bool) + +infraCommand [string](https://godoc.org/builtin#string) + +infraImage [string](https://godoc.org/builtin#string) + +publish [[]string](#[]string) ### <a name="PodmanInfo"></a>type PodmanInfo PodmanInfo describes the Podman host and build diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 3351123ed..a1aeb6042 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -280,7 +280,9 @@ func getImagesTemplateOutput(ctx context.Context, runtime *libpod.Runtime, image if !opts.noTrunc { imageID = shortID(img.ID()) } + // get all specified repo:tag pairs and print them separately + outer: for repo, tags := range image.ReposToMap(img.Names()) { for _, tag := range tags { size, err := img.Size(ctx) @@ -302,6 +304,10 @@ func getImagesTemplateOutput(ctx context.Context, runtime *libpod.Runtime, image Size: sizeStr, } imagesOutput = append(imagesOutput, params) + if opts.quiet { // Show only one image ID when quiet + break outer + } + } } } diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go index a3364ac4b..967ce7610 100644 --- a/cmd/podman/pod_create.go +++ b/cmd/podman/pod_create.go @@ -3,15 +3,12 @@ package main import ( "fmt" "os" - "strconv" "strings" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/rootless" - "github.com/cri-o/ocicni/pkg/ocicni" - "github.com/docker/go-connections/nat" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli" @@ -150,7 +147,7 @@ func podCreateCmd(c *cli.Context) error { } if len(c.StringSlice("publish")) > 0 { - portBindings, err := CreatePortBindings(c.StringSlice("publish")) + portBindings, err := shared.CreatePortBindings(c.StringSlice("publish")) if err != nil { return err } @@ -178,36 +175,3 @@ func podCreateCmd(c *cli.Context) error { return nil } - -// CreatePortBindings iterates ports mappings and exposed ports into a format CNI understands -func CreatePortBindings(ports []string) ([]ocicni.PortMapping, error) { - var portBindings []ocicni.PortMapping - // The conversion from []string to natBindings is temporary while mheon reworks the port - // deduplication code. Eventually that step will not be required. - _, natBindings, err := nat.ParsePortSpecs(ports) - if err != nil { - return nil, err - } - for containerPb, hostPb := range natBindings { - var pm ocicni.PortMapping - pm.ContainerPort = int32(containerPb.Int()) - for _, i := range hostPb { - var hostPort int - var err error - pm.HostIP = i.HostIP - if i.HostPort == "" { - hostPort = containerPb.Int() - } else { - hostPort, err = strconv.Atoi(i.HostPort) - if err != nil { - return nil, errors.Wrapf(err, "unable to convert host port to integer") - } - } - - pm.HostPort = int32(hostPort) - pm.Protocol = containerPb.Proto() - portBindings = append(portBindings, pm) - } - } - return portBindings, nil -} diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index 0f4f8765b..910c7ba35 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -46,6 +46,13 @@ var ( ) func rmiCmd(c *cli.Context) error { + var ( + lastError error + deleted bool + deleteErr error + msg string + ) + ctx := getContext() if err := validateFlags(c, rmiFlags); err != nil { return err @@ -66,20 +73,18 @@ func rmiCmd(c *cli.Context) error { } images := args[:] - var lastError error - var deleted bool removeImage := func(img *image.Image) { deleted = true - msg, err := runtime.RemoveImage(ctx, img, c.Bool("force")) - if err != nil { - if errors.Cause(err) == storage.ErrImageUsedByContainer { + msg, deleteErr = runtime.RemoveImage(ctx, img, c.Bool("force")) + if deleteErr != nil { + if errors.Cause(deleteErr) == storage.ErrImageUsedByContainer { fmt.Printf("A container associated with containers/storage, i.e. via Buildah, CRI-O, etc., may be associated with this image: %-12.12s\n", img.ID()) } if lastError != nil { fmt.Fprintln(os.Stderr, lastError) } - lastError = err + lastError = deleteErr } else { fmt.Println(msg) } @@ -108,6 +113,14 @@ func rmiCmd(c *cli.Context) error { } lastNumberofImages = len(imagesToDelete) imagesToDelete, err = runtime.ImageRuntime().GetImages() + if err != nil { + return err + } + // If no images are left to delete or there is just one image left and it cannot be deleted, + // lets break out and display the error + if len(imagesToDelete) == 0 || (lastNumberofImages == 1 && lastError != nil) { + break + } } } else { // Create image.image objects for deletion from user input. diff --git a/cmd/podman/shared/pod.go b/cmd/podman/shared/pod.go index 4e8e58c4d..30dd14845 100644 --- a/cmd/podman/shared/pod.go +++ b/cmd/podman/shared/pod.go @@ -1,7 +1,11 @@ package shared import ( + "strconv" + "github.com/containers/libpod/libpod" + "github.com/cri-o/ocicni/pkg/ocicni" + "github.com/docker/go-connections/nat" "github.com/pkg/errors" ) @@ -95,3 +99,36 @@ func GetNamespaceOptions(ns []string) ([]libpod.PodCreateOption, error) { } return options, nil } + +// CreatePortBindings iterates ports mappings and exposed ports into a format CNI understands +func CreatePortBindings(ports []string) ([]ocicni.PortMapping, error) { + var portBindings []ocicni.PortMapping + // The conversion from []string to natBindings is temporary while mheon reworks the port + // deduplication code. Eventually that step will not be required. + _, natBindings, err := nat.ParsePortSpecs(ports) + if err != nil { + return nil, err + } + for containerPb, hostPb := range natBindings { + var pm ocicni.PortMapping + pm.ContainerPort = int32(containerPb.Int()) + for _, i := range hostPb { + var hostPort int + var err error + pm.HostIP = i.HostIP + if i.HostPort == "" { + hostPort = containerPb.Int() + } else { + hostPort, err = strconv.Atoi(i.HostPort) + if err != nil { + return nil, errors.Wrapf(err, "unable to convert host port to integer") + } + } + + pm.HostPort = int32(hostPort) + pm.Protocol = containerPb.Proto() + portBindings = append(portBindings, pm) + } + } + return portBindings, nil +} diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index e596a5c91..376bbc950 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -343,15 +343,17 @@ type ListPodContainerInfo ( ) # PodCreate is an input structure for creating pods. -# It emulates options to podman pod create, however -# changing pause image name and pause container -# is not currently supported +# It emulates options to podman pod create. The infraCommand and +# infraImage options are currently NotSupported. type PodCreate ( name: string, cgroupParent: string, labels: [string]string, share: []string, - infra: bool + infra: bool, + infraCommand: string, + infraImage: string, + publish: []string ) # ListPodData is the returned struct for an individual pod @@ -632,7 +634,7 @@ method HistoryImage(name: string) -> (history: []ImageHistory) # and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior). # It will return an [ImageNotFound](#ImageNotFound) error if # the image cannot be found in local storage; otherwise the ID of the image will be returned on success. -method PushImage(name: string, tag: string, tlsverify: bool) -> (image: string) +method PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (image: string) # TagImage takes the name or ID of an image in local storage as well as the desired tag name. If the image cannot # be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success. @@ -700,7 +702,7 @@ method ExportImage(name: string, destination: string, compress: bool, tags: []st # "id": "426866d6fa419873f97e5cbd320eeb22778244c1dfffa01c944db3114f55772e" # } # ~~~ -method PullImage(name: string) -> (id: string) +method PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: bool) -> (id: string) # CreatePod creates a new empty pod. It uses a [PodCreate](#PodCreate) type for input. # On success, the ID of the newly created pod will be returned. diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index 985264f22..51db203fd 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -6,6 +6,19 @@ # Under some contexts these values are not set, make sure they are. export USER="$(whoami)" export HOME="$(getent passwd $USER | cut -d : -f 6)" + +# These are normally set by cirrus, if not use some reasonable defaults +ENVLIB=${ENVLIB:-.bash_profile} +CIRRUS_WORKING_DIR=${CIRRUS_WORKING_DIR:-/var/tmp/go/src/github.com/containers/libpod} +SCRIPT_BASE=${SCRIPT_BASE:-./contrib/cirrus} +PACKER_BASE=${PACKER_BASE:-./contrib/cirrus/packer} +CIRRUS_BUILD_ID=${CIRRUS_BUILD_ID:-DEADBEEF} # a human +cd "$CIRRUS_WORKING_DIR" +CIRRUS_BASE_SHA=${CIRRUS_BASE_SHA:-$(git rev-parse upstream/master || git rev-parse origin/master)} +CIRRUS_CHANGE_IN_REPO=${CIRRUS_CHANGE_IN_REPO:-$(git rev-parse HEAD)} +CIRRUS_REPO_NAME=${CIRRUS_REPO_NAME:-libpod} +cd - + if ! [[ "$PATH" =~ "/usr/local/bin" ]] then export PATH="$PATH:/usr/local/bin" diff --git a/contrib/cirrus/packer/fedora_setup.sh b/contrib/cirrus/packer/fedora_setup.sh index e93c45859..01c468901 100644 --- a/contrib/cirrus/packer/fedora_setup.sh +++ b/contrib/cirrus/packer/fedora_setup.sh @@ -28,7 +28,6 @@ ooe.sh sudo dnf install -y \ atomic-registries \ btrfs-progs-devel \ bzip2 \ - conmon \ device-mapper-devel \ emacs-nox \ findutils \ diff --git a/contrib/cirrus/packer/libpod_base_images.yml b/contrib/cirrus/packer/libpod_base_images.yml index 4ae44e0d9..109b9b8d5 100644 --- a/contrib/cirrus/packer/libpod_base_images.yml +++ b/contrib/cirrus/packer/libpod_base_images.yml @@ -18,10 +18,14 @@ variables: # RHEL requires a subscription to install/update packages RHSM_COMMAND: - # Fedora images are obtainable by direct download + # Latest Fedora release FEDORA_IMAGE_URL: "https://dl.fedoraproject.org/pub/fedora/linux/releases/29/Cloud/x86_64/images/Fedora-Cloud-Base-29-1.2.x86_64.qcow2" FEDORA_CSUM_URL: "https://dl.fedoraproject.org/pub/fedora/linux/releases/29/Cloud/x86_64/images/Fedora-Cloud-29-1.2-x86_64-CHECKSUM" FEDORA_BASE_IMAGE_NAME: 'fedora-cloud-base-29-1-2' # Name to use in GCE + # Prior Fedora release + PRIOR_FEDORA_IMAGE_URL: "https://dl.fedoraproject.org/pub/fedora/linux/releases/28/Cloud/x86_64/images/Fedora-Cloud-Base-28-1.1.x86_64.qcow2" + PRIOR_FEDORA_CSUM_URL: "https://dl.fedoraproject.org/pub/fedora/linux/releases/28/Cloud/x86_64/images/Fedora-Cloud-28-1.1-x86_64-CHECKSUM" + PRIOR_FEDORA_BASE_IMAGE_NAME: 'fedora-cloud-base-28-1-1' # Name to use in GCE FAH_IMAGE_URL: "https://dl.fedoraproject.org/pub/alt/atomic/stable/Fedora-Atomic-29-20181025.1/AtomicHost/x86_64/images/Fedora-AtomicHost-29-20181025.1.x86_64.qcow2" FAH_CSUM_URL: "https://dl.fedoraproject.org/pub/alt/atomic/stable/Fedora-Atomic-29-20181025.1/AtomicHost/x86_64/images/Fedora-AtomicHost-29-20181025.1-x86_64-CHECKSUM" FAH_BASE_IMAGE_NAME: 'fedora-atomichost-29-20181025-1' # Name to use in GCE @@ -101,6 +105,11 @@ builders: ssh_username: 'root' - <<: *nested_virt + name: 'prior_fedora' + iso_url: '{{user `PRIOR_FEDORA_IMAGE_URL`}}' + iso_checksum_url: '{{user `PRIOR_FEDORA_CSUM_URL`}}' + + - <<: *nested_virt name: 'fah' iso_url: '{{user `FAH_IMAGE_URL`}}' iso_checksum_url: '{{user `FAH_CSUM_URL`}}' @@ -152,7 +161,7 @@ provisioners: post-processors: - - type: "compress" - only: ['fedora', 'fah', 'rhel'] + only: ['fedora', 'prior_fedora', 'fah', 'rhel'] output: '/tmp/{{build_name}}/disk.raw.tar.gz' format: '.tar.gz' compression_level: 9 @@ -167,6 +176,11 @@ post-processors: image_description: 'Based on {{user `FEDORA_IMAGE_URL`}}' image_family: '{{user `FEDORA_BASE_IMAGE_NAME`}}' - <<: *gcp_import + only: ['prior_fedora'] + image_name: "{{user `PRIOR_FEDORA_BASE_IMAGE_NAME`}}-{{user `TIMESTAMP`}}" + image_description: 'Based on {{user `PRIOR_FEDORA_IMAGE_URL`}}' + image_family: '{{user `PRIOR_FEDORA_BASE_IMAGE_NAME`}}' + - <<: *gcp_import only: ['fah'] image_name: "{{user `FAH_BASE_IMAGE_NAME`}}-{{user `TIMESTAMP`}}" image_description: 'Based on {{user `FAH_IMAGE_URL`}}' diff --git a/contrib/cirrus/packer/libpod_images.yml b/contrib/cirrus/packer/libpod_images.yml index 7b95b08cc..d31c11a8d 100644 --- a/contrib/cirrus/packer/libpod_images.yml +++ b/contrib/cirrus/packer/libpod_images.yml @@ -7,6 +7,7 @@ variables: CENTOS_BASE_IMAGE: '{{env `CENTOS_BASE_IMAGE`}}' UBUNTU_BASE_IMAGE: '{{env `UBUNTU_BASE_IMAGE`}}' FEDORA_BASE_IMAGE: '{{env `FEDORA_BASE_IMAGE`}}' + PRIOR_FEDORA_BASE_IMAGE: '{{env `PRIOR_FEDORA_BASE_IMAGE`}}' FAH_BASE_IMAGE: '{{env `FAH_BASE_IMAGE`}}' # libpod dependencies to build and install into images @@ -67,6 +68,10 @@ builders: source_image: '{{user `FEDORA_BASE_IMAGE`}}' - <<: *gce_hosted_image + name: 'fedora-28' + source_image: '{{user `PRIOR_FEDORA_BASE_IMAGE`}}' + + - <<: *gce_hosted_image name: 'fah-29' source_image: '{{user `FAH_BASE_IMAGE`}}' diff --git a/contrib/cirrus/packer/prior_fedora_base-setup.sh b/contrib/cirrus/packer/prior_fedora_base-setup.sh new file mode 120000 index 000000000..998a5d9fd --- /dev/null +++ b/contrib/cirrus/packer/prior_fedora_base-setup.sh @@ -0,0 +1 @@ +fedora_base-setup.sh
\ No newline at end of file diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index 5ba842cf1..174bd3daf 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -4,7 +4,6 @@ set -e source $(dirname $0)/lib.sh req_env_var " -CI $CI USER $USER HOME $HOME ENVLIB $ENVLIB @@ -58,7 +57,11 @@ then envstr='export BUILDTAGS="seccomp $($GOSRC/hack/btrfs_tag.sh) $($GOSRC/hack/btrfs_installed_tag.sh) $($GOSRC/hack/ostree_tag.sh) varlink exclude_graphdriver_devicemapper"' ;; fedora-29) ;& # Continue to the next item - fedora-28) ;& + fedora-28) + RUNC="https://kojipkgs.fedoraproject.org/packages/runc/1.0.0/55.dev.git578fe65.fc${OS_RELEASE_VER}/x86_64/runc-1.0.0-55.dev.git578fe65.fc${OS_RELEASE_VER}.x86_64.rpm" + echo ">>>>> OVERRIDING RUNC WITH $RUNC <<<<<" + dnf -y install "$RUNC" + ;& # Continue to the next item centos-7) ;& rhel-7) envstr='unset BUILDTAGS' # Use default from Makefile diff --git a/contrib/cirrus/unit_test.sh b/contrib/cirrus/unit_test.sh index e5b167e79..61d9dc73d 100755 --- a/contrib/cirrus/unit_test.sh +++ b/contrib/cirrus/unit_test.sh @@ -20,6 +20,7 @@ case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in make "BUILDTAGS=$BUILDTAGS" ;; fedora-29) ;& # Continue to the next item + fedora-28) ;& centos-7) ;& rhel-7) make install.tools diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh new file mode 100755 index 000000000..e9a755dd4 --- /dev/null +++ b/hack/get_ci_vm.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +set -e + +cd $(dirname $0)/../ + +VMNAME="${USER}-twidling-$1" +# TODO: Many/most of these values should come from .cirrus.yml +ZONE="us-central1-a" +CPUS="2" +MEMORY="4Gb" +DISK="200" +PROJECT="libpod-218412" +GOSRC="/var/tmp/go/src/github.com/containers/libpod" + +PGCLOUD="sudo podman run -it --rm -e AS_ID=$UID -e AS_USER=$USER -v /home/$USER:$HOME:z quay.io/cevich/gcloud_centos:latest" +CREATE_CMD="$PGCLOUD compute instances create --zone=$ZONE --image=$1 --custom-cpu=$CPUS --custom-memory=$MEMORY --boot-disk-size=$DISK --labels=in-use-by=$USER $VMNAME" +SSH_CMD="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no -F /dev/null" +CLEANUP_CMD="$PGCLOUD compute instances delete --zone $ZONE --delete-disks=all $VMNAME" + +# COLOR! +RED="\e[1;36;41m" +YEL="\e[1;33;44m" +NOR="\e[0m" + +if [[ -z "$1" ]] +then + echo -e "\n${RED}Error: No image-name specified. Some possible values (from .cirrus.yml).${NOR}" + egrep 'image_name' ".cirrus.yml" | grep -v '#' | cut -d: -f 2 | tr -d [:blank:] + exit 1 +fi + +echo -e "\n${YEL}WARNING: This will not work without local sudo access to run podman,${NOR}" +echo -e " ${YEL}and prior authorization to use the libpod GCP project. Also,${NOR}" +echo -e " ${YEL}possession of the proper ssh private key is required.${NOR}" + +if [[ "$USER" =~ "root" ]] +then + echo -e "\n${RED}ERROR: This script must be run as a regular user${NOR}" + exit 2 +fi + +if [[ ! -r "$HOME/.config/gcloud/active_config" ]] +then + echo -e "\n${RED}ERROR: Can't find gcloud configuration, attempting to run init.${NOR}" + $PGCLOUD init --project=$PROJECT +fi + +cleanup() { + echo -e "\n${YEL}Deleting $VMNAME ${RED}(Might take a minute or two)${NOR} ++ $CLEANUP_CMD +" + $CLEANUP_CMD # prompts for Yes/No +} + +trap cleanup EXIT + +echo -e "\n${YEL}Trying to creating a VM named $VMNAME (not fatal if already exists).${NOR}" +echo "+ $CREATE_CMD" +$CREATE_CMD || true # allow re-running commands below when "delete: N" + +echo -e "\n${YEL}Attempting to retrieve IP address of existing ${VMNAME}${NOR}." +IP=`$PGCLOUD compute instances list --filter=name=$VMNAME --limit=1 '--format=csv(networkInterfaces.accessConfigs.natIP)' | tr --complement --delete .[:digit:]` + +echo -e "\n${YEL}Creating $GOSRC directory.${NOR}" +SSH_MKDIR="$SSH_CMD root@$IP mkdir -vp $GOSRC" +echo "+ $SSH_MKDIR" +$SSH_MKDIR + +echo -e "\n${YEL}Synchronizing local repository to $IP:${GOSRC}${NOR} ." +export RSYNC_RSH="$SSH_CMD" +RSYNC_CMD="rsync --quiet --recursive --update --links --safe-links --perms --sparse $PWD/ root@$IP:$GOSRC/" +echo "+ export RSYNC_RSH=\"$SSH_CMD\"" +echo "+ $RSYNC_CMD" +$RSYNC_CMD + +echo -e "\n${YEL}Executing environment setup${NOR}" +ENV_CMD="$SSH_CMD root@$IP env CI=true $GOSRC/contrib/cirrus/setup_environment.sh" +echo "+ $ENV_CMD" +$SSH_CMD root@$IP $GOSRC/contrib/cirrus/setup_environment.sh + +echo -e "\n${YEL}Connecting to $VMNAME ${RED}(option to delete VM upon logout).${NOR}" +SSH_CMD="$SSH_CMD -t root@$IP" +echo "+ $SSH_CMD" +$SSH_CMD "cd $GOSRC ; bash -il" diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index a5673f636..5e4cb4ccb 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -13,7 +13,9 @@ import ( "github.com/containers/buildah" "github.com/containers/buildah/imagebuildah" "github.com/containers/image/docker" + dockerarchive "github.com/containers/image/docker/archive" "github.com/containers/image/manifest" + "github.com/containers/image/transports/alltransports" "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/cmd/podman/varlink" @@ -130,7 +132,7 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI if config.Pull_always { pullPolicy = imagebuildah.PullAlways } - manifestType := "oci" + manifestType := "oci" //nolint if config.Image_format != "" { manifestType = config.Image_format } @@ -311,8 +313,12 @@ func (i *LibpodAPI) HistoryImage(call iopodman.VarlinkCall, name string) error { } // PushImage pushes an local image to registry -// TODO We need to add options for signing, credentials, tls, and multi-tag -func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVerify bool) error { +func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVerify bool, signaturePolicy, creds, certDir string, compress bool, format string, removeSignatures bool, signBy string) error { + var ( + registryCreds *types.DockerAuthConfig + manifestType string + ) + newImage, err := i.Runtime.ImageRuntime().NewFromLocal(name) if err != nil { return call.ReplyImageNotFound(err.Error()) @@ -321,15 +327,38 @@ func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVe if tag != "" { destname = tag } - - dockerRegistryOptions := image.DockerRegistryOptions{} + if creds != "" { + creds, err := util.ParseRegistryCreds(creds) + if err != nil { + return err + } + registryCreds = creds + } + dockerRegistryOptions := image.DockerRegistryOptions{ + DockerRegistryCreds: registryCreds, + DockerCertPath: certDir, + } if !tlsVerify { dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.OptionalBoolTrue } + if format != "" { + switch format { + case "oci": //nolint + manifestType = v1.MediaTypeImageManifest + case "v2s1": + manifestType = manifest.DockerV2Schema1SignedMediaType + case "v2s2", "docker": + manifestType = manifest.DockerV2Schema2MediaType + default: + return call.ReplyErrorOccurred(fmt.Sprintf("unknown format %q. Choose on of the supported formats: 'oci', 'v2s1', or 'v2s2'", format)) + } + } + so := image.SigningOptions{ + RemoveSignatures: removeSignatures, + SignBy: signBy, + } - so := image.SigningOptions{} - - if err := newImage.PushImageToHeuristicDestination(getContext(), destname, "", "", "", nil, false, so, &dockerRegistryOptions, nil); err != nil { + if err := newImage.PushImageToHeuristicDestination(getContext(), destname, manifestType, "", signaturePolicy, nil, compress, so, &dockerRegistryOptions, nil); err != nil { return call.ReplyErrorOccurred(err.Error()) } return call.ReplyPushImage(newImage.ID()) @@ -428,7 +457,7 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch sc := image.GetSystemContext(i.Runtime.GetConfig().SignaturePolicyPath, "", false) var mimeType string switch manifestType { - case "oci", "": + case "oci", "": //nolint mimeType = buildah.OCIv1ImageManifest case "docker": mimeType = manifest.DockerV2Schema2MediaType @@ -496,13 +525,47 @@ func (i *LibpodAPI) ExportImage(call iopodman.VarlinkCall, name, destination str } // PullImage pulls an image from a registry to the image store. -// TODO This implementation is incomplete -func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error { - newImage, err := i.Runtime.ImageRuntime().New(getContext(), name, "", "", nil, &image.DockerRegistryOptions{}, image.SigningOptions{}, true) - if err != nil { - return call.ReplyErrorOccurred(fmt.Sprintf("unable to pull %s: %s", name, err.Error())) +func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string, certDir, creds, signaturePolicy string, tlsVerify bool) error { + var ( + registryCreds *types.DockerAuthConfig + imageID string + ) + if creds != "" { + creds, err := util.ParseRegistryCreds(creds) + if err != nil { + return err + } + registryCreds = creds + } + + dockerRegistryOptions := image.DockerRegistryOptions{ + DockerRegistryCreds: registryCreds, + DockerCertPath: certDir, + } + if tlsVerify { + dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!tlsVerify) + } + + so := image.SigningOptions{} + + if strings.HasPrefix(name, dockerarchive.Transport.Name()+":") { + srcRef, err := alltransports.ParseImageName(name) + if err != nil { + return errors.Wrapf(err, "error parsing %q", name) + } + newImage, err := i.Runtime.ImageRuntime().LoadFromArchiveReference(getContext(), srcRef, signaturePolicy, nil) + if err != nil { + return errors.Wrapf(err, "error pulling image from %q", name) + } + imageID = newImage[0].ID() + } else { + newImage, err := i.Runtime.ImageRuntime().New(getContext(), name, signaturePolicy, "", nil, &dockerRegistryOptions, so, false) + if err != nil { + return call.ReplyErrorOccurred(fmt.Sprintf("unable to pull %s: %s", name, err.Error())) + } + imageID = newImage.ID() } - return call.ReplyPullImage(newImage.ID()) + return call.ReplyPullImage(imageID) } // ImageExists returns bool as to whether the input image exists in local storage diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go index 461371497..6e758786a 100644 --- a/pkg/varlinkapi/pods.go +++ b/pkg/varlinkapi/pods.go @@ -2,6 +2,7 @@ package varlinkapi import ( "encoding/json" + "github.com/containers/libpod/pkg/rootless" "syscall" "github.com/containers/libpod/cmd/podman/shared" @@ -12,6 +13,10 @@ import ( // CreatePod ... func (i *LibpodAPI) CreatePod(call iopodman.VarlinkCall, create iopodman.PodCreate) error { var options []libpod.PodCreateOption + + if create.InfraCommand != "" || create.InfraImage != "" { + return call.ReplyErrorOccurred("the infra-command and infra-image options are not supported yet") + } if create.CgroupParent != "" { options = append(options, libpod.WithPodCgroupParent(create.CgroupParent)) } @@ -27,6 +32,21 @@ func (i *LibpodAPI) CreatePod(call iopodman.VarlinkCall, create iopodman.PodCrea if len(create.Share) == 0 && create.Infra { return call.ReplyErrorOccurred("You must share kernel namespaces to run an infra container") } + + if len(create.Publish) > 0 { + if !create.Infra { + return call.ReplyErrorOccurred("you must have an infra container to publish port bindings to the host") + } + if rootless.IsRootless() { + return call.ReplyErrorOccurred("rootless networking does not allow port binding to the host") + } + portBindings, err := shared.CreatePortBindings(create.Publish) + if err != nil { + return err + } + options = append(options, libpod.WithInfraContainerPorts(portBindings)) + + } if create.Infra { options = append(options, libpod.WithInfraContainer()) nsOptions, err := shared.GetNamespaceOptions(create.Share) diff --git a/test/README.md b/test/README.md index 2a9a4d4b1..fd72ecd00 100644 --- a/test/README.md +++ b/test/README.md @@ -79,7 +79,7 @@ switch is optional. 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/your_test.go +GOPATH=~/go go test -v test/e2e/libpod_suite_test.go test/e2e/config.go test/e2e/config_amd64.go test/e2e/your_test.go ``` #### Run all tests like PAPR diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index fe614e911..57322643e 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "os" + "strconv" "github.com/containers/libpod/pkg/criu" . "github.com/containers/libpod/test/utils" @@ -29,8 +30,9 @@ var _ = Describe("Podman checkpoint", func() { Skip("CRIU is missing or too old.") } hostInfo := podmanTest.Host - if hostInfo.Distribution == "fedora" && hostInfo.Version == "29" { - Skip("Checkpoint tests appear to fail on F29.") + hostDistVer, _ := strconv.Atoi(hostInfo.Version) + if hostInfo.Distribution == "fedora" && hostDistVer <= 29 { + Skip("Checkpoint tests appear to fail on older (<30) Fedora versions .") } }) diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index a927088ca..af32c032b 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -63,6 +63,10 @@ var _ = Describe("Podman images", func() { session.LineInOutputContainsTag("foo", "c") session.LineInOutputContainsTag("bar", "a") session.LineInOutputContainsTag("bar", "b") + session = podmanTest.Podman([]string{"images", "-qn"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 2)) }) It("podman images with digests", func() { diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go index 268db5aa1..d312124ab 100644 --- a/test/e2e/libpod_suite_test.go +++ b/test/e2e/libpod_suite_test.go @@ -109,7 +109,7 @@ func PodmanTestCreate(tempDir string) *PodmanTestIntegration { } conmonBinary := filepath.Join("/usr/libexec/podman/conmon") altConmonBinary := "/usr/libexec/crio/conmon" - if _, err := os.Stat(altConmonBinary); err == nil { + if _, err := os.Stat(conmonBinary); os.IsNotExist(err) { conmonBinary = altConmonBinary } if os.Getenv("CONMON_BINARY") != "" { |