diff options
36 files changed, 246 insertions, 114 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index d3a9eea40..0efe73802 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -31,7 +31,7 @@ env: PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-28-libpod-7f4cd1f7" UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-libpod-7f4cd1f7" # RHEL_CACHE_IMAGE_NAME: "rhel-8-notready" - # PRIOR_RHEL_CACHE_IMAGE_NAME: "rhel-7-libpod-7f4cd1f7" + PRIOR_RHEL_CACHE_IMAGE_NAME: "rhel-7-libpod-7f4cd1f7" # CENTOS_CACHE_IMAGE_NAME: "centos-7-notready" #### @@ -45,9 +45,9 @@ 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,fedora-28" # TODO: fah-29,rhel-7,centos-7 + PACKER_BUILDS: "ubuntu-18,fedora-29,fedora-28,rhel-7" # TODO: rhel-8,centos-7 # Version of packer to use - PACKER_VER: "1.3.1" + PACKER_VER: "1.3.2" # Special image w/ nested-libvirt + tools for creating new cache and base images IMAGE_BUILDER_CACHE_IMAGE_NAME: "image-builder-image-1541772081" # Google-maintained base-image names @@ -58,7 +58,7 @@ env: 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" + RHEL_BASE_IMAGE: "rhel-guest-image-7-6-210-x86-64-qcow2-1548099756" #### #### Credentials and other secret-sauces, decrypted at runtime when authorized. @@ -134,6 +134,7 @@ build_each_commit_task: - git fetch --depth $CIRRUS_CLONE_DEPTH origin $CIRRUS_BASE_BRANCH - env GOPATH=/var/tmp/go/ make build-all-new-commits GIT_BASE_BRANCH=origin/$CIRRUS_BASE_BRANCH + # This task does the unit and integration testing for every platform testing_task: @@ -154,10 +155,10 @@ testing_task: image_name: "${FEDORA_CACHE_IMAGE_NAME}" image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" image_name: "${UBUNTU_CACHE_IMAGE_NAME}" + image_name: "${PRIOR_RHEL_CACHE_IMAGE_NAME}" # TODO: tests fail - # image_name: "${RHEL_CACHE_IMAGE_NAME} - # image_name: "${PRIOR_RHEL_CACHE_IMAGE_NAME} + # image_name: "${RHEL_CACHE_IMAGE_NAME}" # image_name: "${CENTOS_CACHE_IMAGE_NAME}" timeout_in: 120m @@ -191,9 +192,9 @@ optional_testing_task: image_name: "${FEDORA_CACHE_IMAGE_NAME}" image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}" image_name: "${UBUNTU_CACHE_IMAGE_NAME}" + image_name: "${PRIOR_RHEL_CACHE_IMAGE_NAME}" # TODO: Make these work (also build_images_task below) - # image_name: "${RHEL_CACHE_IMAGE_NAME} - # image_name: "${PRIOR_RHEL_CACHE_IMAGE_NAME} + # image_name: "${RHEL_CACHE_IMAGE_NAME}" # image_name: "${CENTOS_CACHE_IMAGE_NAME}" timeout_in: 60m @@ -65,7 +65,7 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func ImageExists(name: string) int](#ImageExists) -[func ImagesPrune() []string](#ImagesPrune) +[func ImagesPrune(all: bool) []string](#ImagesPrune) [func ImportImage(source: string, reference: string, message: string, changes: []string) string](#ImportImage) @@ -580,7 +580,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.ImageExists '{"name": "im ### <a name="ImagesPrune"></a>func ImagesPrune <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method ImagesPrune() [[]string](#[]string)</div> +method ImagesPrune(all: [bool](https://godoc.org/builtin#bool)) [[]string](#[]string)</div> ImagesPrune removes all unused images from the local store. Upon successful pruning, the IDs of the removed images are returned. ### <a name="ImportImage"></a>func ImportImage @@ -224,6 +224,7 @@ install: .gopathok install.bin install.man install.cni install.systemd install.bin: install ${SELINUXOPT} -d -m 755 $(BINDIR) install ${SELINUXOPT} -m 755 bin/podman $(BINDIR)/podman + test -z "${SELINUXOPT}" || chcon --verbose --reference=$(BINDIR)/podman bin/podman install.man: docs install ${SELINUXOPT} -d -m 755 $(MANDIR)/man1 diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 065d08df4..c56efa153 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -128,7 +129,12 @@ func createContainer(c *cli.Context, runtime *libpod.Runtime) (*libpod.Container var data *inspect.ImageData = nil if rootfs == "" && !rootless.SkipStorageSetup() { - newImage, err := runtime.ImageRuntime().New(ctx, c.Args()[0], rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{}, false) + var writer io.Writer + if !c.Bool("quiet") { + writer = os.Stderr + } + + newImage, err := runtime.ImageRuntime().New(ctx, c.Args()[0], rtc.SignaturePolicyPath, "", writer, nil, image.SigningOptions{}, false) if err != nil { return nil, nil, err } diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 031f06618..d4f405975 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -188,13 +188,6 @@ func imagesCmd(c *cli.Context) error { } opts.outputformat = opts.setOutputFormat() - /* - podman does not implement --all for images - - intermediate images are only generated during the build process. they are - children to the image once built. until buildah supports caching builds, - it will not generate these intermediate images. - */ images, err := runtime.GetImages() if err != nil { return errors.Wrapf(err, "unable to get images") diff --git a/cmd/podman/images_prune.go b/cmd/podman/images_prune.go index 06879e02d..aef387732 100644 --- a/cmd/podman/images_prune.go +++ b/cmd/podman/images_prune.go @@ -2,7 +2,7 @@ package main import ( "fmt" - "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" "github.com/urfave/cli" ) @@ -13,33 +13,36 @@ var ( Removes all unnamed images from local storage ` - + pruneImageFlags = []cli.Flag{ + cli.BoolFlag{ + Name: "all, a", + Usage: "remove all unused images, not just dangling ones", + }, + } pruneImagesCommand = cli.Command{ Name: "prune", Usage: "Remove unused images", Description: pruneImagesDescription, Action: pruneImagesCmd, OnUsageError: usageErrorHandler, + Flags: pruneImageFlags, } ) func pruneImagesCmd(c *cli.Context) error { - runtime, err := libpodruntime.GetRuntime(c) + runtime, err := adapter.GetRuntime(c) if err != nil { return errors.Wrapf(err, "could not get runtime") } defer runtime.Shutdown(false) - pruneImages, err := runtime.ImageRuntime().GetPruneImages() - if err != nil { - return err - } - - for _, i := range pruneImages { - if err := i.Remove(true); err != nil { - return errors.Wrapf(err, "failed to remove %s", i.ID()) + // Call prune; if any cids are returned, print them and then + // return err in case an error also came up + pruneCids, err := runtime.PruneImages(c.Bool("all")) + if len(pruneCids) > 0 { + for _, cid := range pruneCids { + fmt.Println(cid) } - fmt.Println(i.ID()) } - return nil + return err } diff --git a/cmd/podman/info.go b/cmd/podman/info.go index 3888829a3..f5f91b603 100644 --- a/cmd/podman/info.go +++ b/cmd/podman/info.go @@ -29,7 +29,7 @@ var ( Usage: "display additional debug information", }, cli.StringFlag{ - Name: "format", + Name: "format, f", Usage: "Change the output format to JSON or a Go template", }, } diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go index 3ef740463..5595a8331 100644 --- a/cmd/podman/inspect.go +++ b/cmd/podman/inspect.go @@ -32,7 +32,7 @@ var ( Usage: "Change the output format to a Go template", }, cli.BoolFlag{ - Name: "size", + Name: "size, s", Usage: "Display total file size if the type is container", }, LatestFlag, diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index 0ad3f4c73..1708c671c 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -606,19 +606,50 @@ func portsToString(ports []ocicni.PortMapping) string { } func printFormat(format string, containers []shared.PsContainerOutput) error { - out := template.New("output") - out, err := out.Parse(format + "\n") + // return immediately if no containers are present + if len(containers) == 0 { + return nil + } + + // Use a tabwriter to align column format + w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) + + // Make a map of the field names for the headers + headerNames := make(map[string]string) + v := reflect.ValueOf(containers[0]) + t := v.Type() + for i := 0; i < t.NumField(); i++ { + headerNames[t.Field(i).Name] = t.Field(i).Name + } + + // Spit out the header if "table" is present in the format + if strings.HasPrefix(format, "table") { + hformat := strings.Replace(strings.TrimSpace(format[5:]), " ", "\t", -1) + format = hformat + headerTmpl, err := template.New("header").Parse(hformat) + if err != nil { + return err + } + if err := headerTmpl.Execute(w, headerNames); err != nil { + return err + } + fmt.Fprintln(w, "") + } + // Spit out the data rows now + dataTmpl, err := template.New("data").Parse(format) if err != nil { return err } + for _, container := range containers { - if err := out.Execute(os.Stdout, container); err != nil { + if err := dataTmpl.Execute(w, container); err != nil { return err } - + fmt.Fprintln(w, "") } - return nil + // Flush the writer + return w.Flush() } func dumpJSON(containers []shared.PsContainerOutput) error { diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 244a8eaf5..8b02057a1 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -1017,7 +1017,7 @@ method UnmountContainer(name: string, force: bool) -> () # ImagesPrune removes all unused images from the local store. Upon successful pruning, # the IDs of the removed images are returned. -method ImagesPrune() -> (pruned: []string) +method ImagesPrune(all: bool) -> (pruned: []string) # This function is not implemented yet. method ListContainerPorts(name: string) -> (notimplemented: NotImplemented) diff --git a/cmd/podman/version.go b/cmd/podman/version.go index fd7f06b7c..ce773ee2e 100644 --- a/cmd/podman/version.go +++ b/cmd/podman/version.go @@ -57,7 +57,7 @@ var ( } versionFlags = []cli.Flag{ cli.StringFlag{ - Name: "format", + Name: "format, f", Usage: "Change the output format to JSON or a Go template", }, } diff --git a/completions/bash/podman b/completions/bash/podman index 08891563c..e0de4586c 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -1219,6 +1219,7 @@ _podman_info() { --debug " local options_with_args=" + -f --format " @@ -1366,6 +1367,7 @@ _podman_inspect() { --type -t --size + -s " local all_options="$options_with_args $boolean_options" @@ -2036,6 +2038,7 @@ _podman_version() { " local options_with_args=" --format + -f " local all_options="$options_with_args $boolean_options" @@ -2459,6 +2462,8 @@ _podman_images_prune() { " local boolean_options=" + -a + --all -h --help " diff --git a/contrib/cirrus/build_vm_images.sh b/contrib/cirrus/build_vm_images.sh index ee45b1ead..6b86aa4d4 100755 --- a/contrib/cirrus/build_vm_images.sh +++ b/contrib/cirrus/build_vm_images.sh @@ -42,15 +42,33 @@ then fi fi -set -x - cd "$GOSRC/$PACKER_BASE" + +# Separate PR-produced images from those produced on master. +if [[ "${CIRRUS_BRANCH:-}" == "master" ]] +then + POST_MERGE_BUCKET_SUFFIX="-master" +else + POST_MERGE_BUCKET_SUFFIX="" +fi + make libpod_images \ PACKER_BUILDS=$PACKER_BUILDS \ PACKER_VER=$PACKER_VER \ GOSRC=$GOSRC \ SCRIPT_BASE=$SCRIPT_BASE \ PACKER_BASE=$PACKER_BASE \ + POST_MERGE_BUCKET_SUFFIX=$POST_MERGE_BUCKET_SUFFIX \ BUILT_IMAGE_SUFFIX=$BUILT_IMAGE_SUFFIX record_timestamp "cache-image build end" + +# When successful, upload manifest of produced images using a filename unique +# to this build. +URI="gs://packer-import${POST_MERGE_BUCKET_SUFFIX}/manifest${BUILT_IMAGE_SUFFIX}.json" +gsutil cp packer-manifest.json "$URI" + +echo "Finished." +echo "Any tarball URI's referenced above at at $URI" +echo "may be used to create VM images suitable for use in" +echo ".cirrus.yml as values for the 'image_name' keys." diff --git a/contrib/cirrus/integration_test.sh b/contrib/cirrus/integration_test.sh index 627864f47..58c8af289 100755 --- a/contrib/cirrus/integration_test.sh +++ b/contrib/cirrus/integration_test.sh @@ -17,9 +17,9 @@ set -x cd "$GOSRC" case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in ubuntu-18) - make install PREFIX=/usr ETCDIR=/etc "BUILDTAGS=$BUILDTAGS" - make test-binaries "BUILDTAGS=$BUILDTAGS" - SKIP_USERNS=1 make localintegration "BUILDTAGS=$BUILDTAGS" + make install PREFIX=/usr ETCDIR=/etc + make test-binaries + SKIP_USERNS=1 make localintegration ;; fedora-29) ;& # Continue to the next item fedora-28) ;& diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index 32b2c91a5..39e6c7699 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -199,7 +199,7 @@ install_runc_from_git(){ cd "$DEST" ooe.sh git fetch origin --tags ooe.sh git checkout -q "$RUNC_COMMIT" - ooe.sh make static BUILDTAGS="seccomp selinux" + ooe.sh make static BUILDTAGS="seccomp apparmor selinux" sudo install -m 755 runc /usr/bin/runc cd $wd } diff --git a/contrib/cirrus/packer/Makefile b/contrib/cirrus/packer/Makefile index 9bf27373e..0a783e979 100644 --- a/contrib/cirrus/packer/Makefile +++ b/contrib/cirrus/packer/Makefile @@ -3,7 +3,7 @@ # builder name(s) from applicable YAML file, # e.g for names see libpod_images.yml -PACKER_VER ?= 1.3.1 +PACKER_VER ?= 1.3.2 PACKER_DIST_FILENAME := packer_${PACKER_VER}_linux_amd64.zip # Only needed for libpod_base_images target @@ -11,6 +11,7 @@ TIMESTAMP := $(shell date +%s) GOSRC ?= $(shell realpath "./../../../") PACKER_BASE ?= contrib/cirrus/packer SCRIPT_BASE ?= contrib/cirrus +POST_MERGE_BUCKET_SUFFIX ?= # For debugging nested-virt, use #TTYDEV := $(shell tty) @@ -50,10 +51,6 @@ endif -var PACKER_BASE=$(PACKER_BASE) \ -var SCRIPT_BASE=$(SCRIPT_BASE) \ libpod_images.json - @echo "" - @echo "Finished. The images mentioned above, and in packer-manifest.json" - @echo "can be used in .cirrus.yml as values for the 'image_name' keys" - @echo "" cidata.ssh: ssh-keygen -f $@ -P "" -q @@ -100,9 +97,6 @@ endif -var RHEL_IMAGE_FILE=$(RHEL_IMAGE_FILE) \ -var RHEL_CSUM_FILE=$(RHEL_CSUM_FILE) \ -var 'RHSM_COMMAND=$(RHSM_COMMAND)' \ + -var POST_MERGE_BUCKET_SUFFIX=$(POST_MERGE_BUCKET_SUFFIX) \ -only $(PACKER_BUILDS) \ libpod_base_images.json - @echo "" - @echo "Finished. The images mentioned above, and in packer-manifest.json" - @echo "can be used in .cirrus.yml as values for the *_BASE_IMAGE keys." - @echo "" diff --git a/contrib/cirrus/packer/centos_setup.sh b/contrib/cirrus/packer/centos_setup.sh index a13050569..923f2563b 100644 --- a/contrib/cirrus/packer/centos_setup.sh +++ b/contrib/cirrus/packer/centos_setup.sh @@ -25,6 +25,7 @@ ooe.sh sudo yum -y update ooe.sh sudo yum -y install centos-release-scl epel-release ooe.sh sudo yum -y install \ + PyYAML \ atomic-registries \ btrfs-progs-devel \ bzip2 \ diff --git a/contrib/cirrus/packer/image-builder-image_base-setup.sh b/contrib/cirrus/packer/image-builder-image_base-setup.sh index b8e2824a7..8cf9fd8ab 100644 --- a/contrib/cirrus/packer/image-builder-image_base-setup.sh +++ b/contrib/cirrus/packer/image-builder-image_base-setup.sh @@ -45,10 +45,13 @@ ooe.sh sudo yum -y install \ qemu-kvm-tools \ qemu-user \ rsync \ + rng-tools \ unzip \ util-linux \ vim +sudo systemctl enable rngd + sudo ln -s /usr/libexec/qemu-kvm /usr/bin/ sudo tee /etc/modprobe.d/kvm-nested.conf <<EOF diff --git a/contrib/cirrus/packer/libpod_base_images.yml b/contrib/cirrus/packer/libpod_base_images.yml index 109b9b8d5..bf568b40e 100644 --- a/contrib/cirrus/packer/libpod_base_images.yml +++ b/contrib/cirrus/packer/libpod_base_images.yml @@ -105,7 +105,7 @@ builders: ssh_username: 'root' - <<: *nested_virt - name: 'prior_fedora' + name: 'prior-fedora' iso_url: '{{user `PRIOR_FEDORA_IMAGE_URL`}}' iso_checksum_url: '{{user `PRIOR_FEDORA_CSUM_URL`}}' @@ -161,7 +161,7 @@ provisioners: post-processors: - - type: "compress" - only: ['fedora', 'prior_fedora', 'fah', 'rhel'] + only: ['fedora', 'prior-fedora', 'fah', 'rhel'] output: '/tmp/{{build_name}}/disk.raw.tar.gz' format: '.tar.gz' compression_level: 9 @@ -171,12 +171,12 @@ post-processors: project_id: '{{user `GCP_PROJECT_ID`}}' account_file: '{{user `GOOGLE_APPLICATION_CREDENTIALS`}}' bucket: '{{user `XFERBUCKET`}}' - gcs_object_name: '{{build_name}}-{{user `TIMESTAMP`}}-{{uuid}}.tar.gz' + gcs_object_name: '{{build_name}}-{{user `TIMESTAMP`}}.tar.gz' image_name: "{{user `FEDORA_BASE_IMAGE_NAME`}}-{{user `TIMESTAMP`}}" image_description: 'Based on {{user `FEDORA_IMAGE_URL`}}' image_family: '{{user `FEDORA_BASE_IMAGE_NAME`}}' - <<: *gcp_import - only: ['prior_fedora'] + 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`}}' diff --git a/contrib/cirrus/packer/libpod_images.yml b/contrib/cirrus/packer/libpod_images.yml index d31c11a8d..30ad0723a 100644 --- a/contrib/cirrus/packer/libpod_images.yml +++ b/contrib/cirrus/packer/libpod_images.yml @@ -29,6 +29,10 @@ variables: SERVICE_ACCOUNT: '{{env `SERVICE_ACCOUNT`}}' GOOGLE_APPLICATION_CREDENTIALS: '{{env `GOOGLE_APPLICATION_CREDENTIALS`}}' + # Used to separate images produced during PR testing from those + # produced from post-merge testing. Must be empty for PR testing. + POST_MERGE_BUCKET_SUFFIX: '' + # Don't leak sensitive values in error messages / output sensitive-variables: - 'GCE_SSH_USERNAME' @@ -84,13 +88,18 @@ provisioners: - type: 'shell' script: '{{user `GOSRC`}}/{{user `PACKER_BASE`}}/{{split build_name "-" 0}}_setup.sh' environment_vars: - - 'SCRIPT_BASE={{user `SCRIPT_BASE`}}' + - 'GOSRC=/tmp/libpod' - 'CNI_COMMIT={{user `CNI_COMMIT`}}' - 'FEDORA_CNI_COMMIT={{user `FEDORA_CNI_COMMIT`}}' - 'CRIO_COMMIT={{user `CRIO_COMMIT`}}' - 'CRIU_COMMIT={{user `CRIU_COMMIT`}}' - 'RUNC_COMMIT={{user `RUNC_COMMIT`}}' + - 'SCRIPT_BASE={{user `SCRIPT_BASE`}}' - 'RHSM_COMMAND={{user `RHSM_COMMAND`}}' post-processors: - - - type: 'manifest' + # Store VM disk in GCP storage, where it will expire based on a defined + # lifecycle. This prevents GCE from filling with disused images. + - - type: 'googlecompute-export' + paths: ['gs://packer-import{{user `POST_MERGE_BUCKET_SUFFIX`}}/{{build_name}}{{user `BUILT_IMAGE_SUFFIX`}}.tar.gz'] + - type: 'manifest' # writes packer-manifest.json diff --git a/contrib/cirrus/packer/rhel_base-setup.sh b/contrib/cirrus/packer/rhel_base-setup.sh index 8b2073d4f..fbf9f61af 100644 --- a/contrib/cirrus/packer/rhel_base-setup.sh +++ b/contrib/cirrus/packer/rhel_base-setup.sh @@ -16,6 +16,8 @@ req_env_var " install_ooe +rhsm_enable + echo "Setting up repos" # Frequently needed ooe.sh sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm @@ -32,12 +34,15 @@ gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOM -rhsm_enable +echo "Updating all packages" +ooe.sh sudo yum -y update echo "Installing/removing packages" -ooe.sh sudo yum -y install google-compute-engine google-compute-engine-oslogin -ooe.sh sudo yum -y erase "cloud-init" "rh-amazon-rhui-client*" || true +ooe.sh sudo yum -y install rng-tools google-compute-engine google-compute-engine-oslogin + +echo "Enabling critical services" ooe.sh sudo systemctl enable \ + rngd \ google-accounts-daemon \ google-clock-skew-daemon \ google-instance-setup \ @@ -47,6 +52,29 @@ ooe.sh sudo systemctl enable \ rhel_exit_handler # release subscription! +echo "Configuring boot" +cat << "EOF" | sudo tee /etc/default/grub +GRUB_TIMEOUT=0 +GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" +GRUB_DEFAULT=saved +GRUB_DISABLE_SUBMENU=true +GRUB_TERMINAL="serial console" +GRUB_SERIAL_COMMAND="serial --speed=38400" +GRUB_CMDLINE_LINUX="crashkernel=auto console=ttyS0,38400n8" +GRUB_DISABLE_RECOVERY="true" +EOF +sudo grub2-mkconfig -o /boot/grub2/grub.cfg + +echo "Configuring networking" +ooe.sh sudo nmcli connection modify 'System eth0' 802-3-ethernet.mtu 1460 +ooe.sh sudo nmcli connection modify 'System eth0' connection.autoconnect yes +ooe.sh sudo nmcli connection modify 'System eth0' connection.autoconnect-priority +ooe.sh sudo nmcli connection modify 'System eth0' ipv4.method auto +ooe.sh sudo nmcli connection modify 'System eth0' ipv4.dhcp-send-hostname yes +ooe.sh sudo nmcli connection modify 'System eth0' ipv4.dhcp-timeout 0 +ooe.sh sudo nmcli connection modify 'System eth0' ipv4.never-default no +ooe.sh /usr/bin/google_instance_setup + rh_finalize echo "SUCCESS!" diff --git a/contrib/cirrus/packer/rhel_setup.sh b/contrib/cirrus/packer/rhel_setup.sh index 99376fd65..ac6866a57 100644 --- a/contrib/cirrus/packer/rhel_setup.sh +++ b/contrib/cirrus/packer/rhel_setup.sh @@ -31,6 +31,7 @@ ooe.sh sudo subscription-manager repos \ ooe.sh sudo yum -y update ooe.sh sudo yum -y install \ + PyYAML \ atomic-registries \ btrfs-progs-devel \ bzip2 \ @@ -64,9 +65,11 @@ ooe.sh sudo yum -y install \ protobuf-python \ python \ python2-future \ + python2-pyyaml \ python34-dateutil \ python34-psutil \ python34-pytoml \ + python34-PyYAML \ runc \ skopeo-containers \ unzip \ diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index bcfe7e396..838f3c3f3 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -57,7 +57,6 @@ then ubuntu-18) # Always install runc on Ubuntu install_runc_from_git - 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) @@ -67,11 +66,9 @@ then ;& # Continue to the next item centos-7) ;& rhel-7) - envstr='unset BUILDTAGS' # Use default from Makefile ;; *) bad_os_id_ver ;; esac - X=$(echo "$envstr" | tee -a "$HOME/$ENVLIB") && eval "$X" && echo "$X" # Do the same for golang env. vars go env | while read envline diff --git a/contrib/cirrus/system_test.sh b/contrib/cirrus/system_test.sh index 66974f8c6..cb179407a 100755 --- a/contrib/cirrus/system_test.sh +++ b/contrib/cirrus/system_test.sh @@ -15,12 +15,9 @@ set -x cd "$GOSRC" case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in - ubuntu-18) - make install.tools "BUILDTAGS=$BUILDTAGS" - make "BUILDTAGS=$BUILDTAGS" - make test-binaries "BUILDTAGS=$BUILDTAGS" - ;; + ubuntu-18) ;& # Continue to the next item fedora-28) ;& + fedora-29) ;& centos-7) ;& rhel-7) make install.tools diff --git a/contrib/cirrus/unit_test.sh b/contrib/cirrus/unit_test.sh index 15403b7a7..fd9e82509 100755 --- a/contrib/cirrus/unit_test.sh +++ b/contrib/cirrus/unit_test.sh @@ -16,12 +16,8 @@ clean_env set -x cd "$GOSRC" case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in - ubuntu-18) - make install.tools "BUILDTAGS=$BUILDTAGS" - make localunit "BUILDTAGS=$BUILDTAGS" - make "BUILDTAGS=$BUILDTAGS" - ;; - fedora-29) ;& # Continue to the next item + ubuntu-18) ;& # Continue to the next item + fedora-29) ;& fedora-28) ;& centos-7) ;& rhel-7) diff --git a/docs/podman-image-prune.1.md b/docs/podman-image-prune.1.md index db76b26e0..df912c380 100644 --- a/docs/podman-image-prune.1.md +++ b/docs/podman-image-prune.1.md @@ -6,23 +6,38 @@ podman-image-prune - Remove all unused images # SYNOPSIS **podman image prune** +[**-a**|**--all**] [**-h**|**--help**] # DESCRIPTION -**podman image prune** removes all unused images from local storage. An unused image -is defined as an image that does not have any containers based on it. +**podman image prune** removes all dangling images from local storage. With the `all` option, +you can delete all unused images. Unused images are dangling images as well as any image that +does not have any containers based on it. + +## OPTIONS +**--all, -a** + +Remove dangling images and images that have no associated containers. ## Examples ## -Remove all unused images from local storage +Remove all dangling images from local storage ``` $ sudo podman image prune f3e20dc537fb04cb51672a5cb6fdf2292e61d411315549391a0d1f64e4e3097e 324a7a3b2e0135f4226ffdd473e4099fd9e477a74230cdc35de69e84c0f9d907 +``` + +Remove all unused images from local storage +``` +$ sudo podman image prune -a +f3e20dc537fb04cb51672a5cb6fdf2292e61d411315549391a0d1f64e4e3097e +324a7a3b2e0135f4226ffdd473e4099fd9e477a74230cdc35de69e84c0f9d907 6125002719feb1ddf3030acab1df6156da7ce0e78e571e9b6e9c250424d6220c 91e732da5657264c6f4641b8d0c4001c218ae6c1adb9dcef33ad00cafd37d8b6 e4e5109420323221f170627c138817770fb64832da7d8fe2babd863148287fca 77a57fa8285e9656dbb7b23d9efa837a106957409ddd702f995605af27a45ebe + ``` ## SEE ALSO diff --git a/docs/podman-info.1.md b/docs/podman-info.1.md index 836a2c420..d3a0658c9 100644 --- a/docs/podman-info.1.md +++ b/docs/podman-info.1.md @@ -19,7 +19,7 @@ Displays information pertinent to the host, current storage stats, configured co Show additional information -**--format** +**--format, -f** Change output format to "json" or a Go template. diff --git a/docs/podman-inspect.1.md b/docs/podman-inspect.1.md index 7bdbcc662..b01bc0f4e 100644 --- a/docs/podman-inspect.1.md +++ b/docs/podman-inspect.1.md @@ -27,7 +27,7 @@ The keys of the returned JSON can be used as the values for the --format flag (s Instead of providing the container name or ID, use the last created container. If you use methods other than Podman to run containers such as CRI-O, the last started container could be from either of those methods. -**--size** +**--size, -s** Display the total file size if the type is a container diff --git a/docs/podman-version.1.md b/docs/podman-version.1.md index 749a33afd..171096587 100644 --- a/docs/podman-version.1.md +++ b/docs/podman-version.1.md @@ -16,7 +16,7 @@ OS, and Architecture. Print usage statement -**--format** +**--format**, **-f** Change output format to "json" or a Go template. diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go index 1f3599082..f4961437e 100644 --- a/libpod/adapter/runtime.go +++ b/libpod/adapter/runtime.go @@ -99,3 +99,8 @@ func (r *LocalRuntime) LookupContainer(idOrName string) (*Container, error) { } return &Container{ctr}, nil } + +// PruneImages is wrapper into PruneImages within the image pkg +func (r *LocalRuntime) PruneImages(all bool) ([]string, error) { + return r.ImageRuntime().PruneImages(all) +} diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go index 7189348bc..f184ce0a9 100644 --- a/libpod/adapter/runtime_remote.go +++ b/libpod/adapter/runtime_remote.go @@ -320,3 +320,6 @@ func (r *LocalRuntime) Config(name string) *libpod.ContainerConfig { return &data } +func (r *LocalRuntime) PruneImages(all bool) ([]string, error) { + return iopodman.ImagesPrune().Call(r.Conn, all) +} diff --git a/libpod/image/prune.go b/libpod/image/prune.go index 6a1f160d5..8602c222c 100644 --- a/libpod/image/prune.go +++ b/libpod/image/prune.go @@ -1,9 +1,11 @@ package image +import "github.com/pkg/errors" + // GetPruneImages returns a slice of images that have no names/unused -func (ir *Runtime) GetPruneImages() ([]*Image, error) { +func (ir *Runtime) GetPruneImages(all bool) ([]*Image, error) { var ( - unamedImages []*Image + pruneImages []*Image ) allImages, err := ir.GetImages() if err != nil { @@ -11,16 +13,35 @@ func (ir *Runtime) GetPruneImages() ([]*Image, error) { } for _, i := range allImages { if len(i.Names()) == 0 { - unamedImages = append(unamedImages, i) + pruneImages = append(pruneImages, i) continue } - containers, err := i.Containers() - if err != nil { - return nil, err + if all { + containers, err := i.Containers() + if err != nil { + return nil, err + } + if len(containers) < 1 { + pruneImages = append(pruneImages, i) + } } - if len(containers) < 1 { - unamedImages = append(unamedImages, i) + } + return pruneImages, nil +} + +// PruneImages prunes dangling and optionally all unused images from the local +// image store +func (ir *Runtime) PruneImages(all bool) ([]string, error) { + var prunedCids []string + pruneImages, err := ir.GetPruneImages(all) + if err != nil { + return nil, errors.Wrap(err, "unable to get images to prune") + } + for _, p := range pruneImages { + if err := p.Remove(true); err != nil { + return nil, errors.Wrap(err, "failed to prune image") } + prunedCids = append(prunedCids, p.ID()) } - return unamedImages, nil + return prunedCids, nil } diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go index 0787b3fa5..2c5022c1f 100644 --- a/pkg/apparmor/apparmor_linux.go +++ b/pkg/apparmor/apparmor_linux.go @@ -214,8 +214,15 @@ func CheckProfileAndLoadDefault(name string) (string, error) { return name, nil } - if name != "" && rootless.IsRootless() { - return "", errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name) + // AppArmor is not supported in rootless mode as it requires root + // privileges. Return an error in case a specific profile is specified. + if rootless.IsRootless() { + if name != "" { + return "", errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name) + } else { + logrus.Debug("skipping loading default AppArmor profile (rootless mode)") + return "", nil + } } if name != "" && !runcaa.IsEnabled() { @@ -230,7 +237,7 @@ func CheckProfileAndLoadDefault(name string) (string, error) { return "", err } if !isLoaded { - return "", fmt.Errorf("AppArmor profile %q specified but not loaded") + return "", fmt.Errorf("AppArmor profile %q specified but not loaded", name) } return name, nil } diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 744f031c0..d6a9b7301 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -627,19 +627,10 @@ func (i *LibpodAPI) ContainerRunlabel(call iopodman.VarlinkCall, input iopodman. } // ImagesPrune .... -func (i *LibpodAPI) ImagesPrune(call iopodman.VarlinkCall) error { - var ( - pruned []string - ) - pruneImages, err := i.Runtime.ImageRuntime().GetPruneImages() +func (i *LibpodAPI) ImagesPrune(call iopodman.VarlinkCall, all bool) error { + prunedImages, err := i.Runtime.ImageRuntime().PruneImages(all) if err != nil { - return err - } - for _, i := range pruneImages { - if err := i.Remove(true); err != nil { - return call.ReplyErrorOccurred(err.Error()) - } - pruned = append(pruned, i.ID()) + return call.ReplyErrorOccurred(err.Error()) } - return call.ReplyImagesPrune(pruned) + return call.ReplyImagesPrune(prunedImages) } diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 50a279232..81fb82b20 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -1,5 +1,3 @@ -// +build !remoteclient - package integration import ( @@ -41,6 +39,7 @@ var _ = Describe("Podman rm", func() { }) It("podman container prune containers", func() { + SkipIfRemote() top := podmanTest.RunTopContainer("") top.WaitWithDefaultTimeout() Expect(top.ExitCode()).To(Equal(0)) @@ -57,6 +56,7 @@ var _ = Describe("Podman rm", func() { }) It("podman image prune none images", func() { + SkipIfRemote() podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true") none := podmanTest.Podman([]string{"images", "-a"}) @@ -74,10 +74,11 @@ var _ = Describe("Podman rm", func() { Expect(none.ExitCode()).To(Equal(0)) hasNoneAfter, _ := after.GrepString("<none>") Expect(hasNoneAfter).To(BeFalse()) + Expect(len(after.OutputToStringArray()) > 1).To(BeTrue()) }) It("podman image prune unused images", func() { - prune := podmanTest.Podman([]string{"image", "prune"}) + prune := podmanTest.Podman([]string{"image", "prune", "-a"}) prune.WaitWithDefaultTimeout() Expect(prune.ExitCode()).To(Equal(0)) diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index bff2427d5..9b1c55bb4 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -7,6 +7,7 @@ import ( "os" "regexp" "sort" + "strings" . "github.com/containers/libpod/test/utils" "github.com/docker/go-units" @@ -148,10 +149,12 @@ var _ = Describe("Podman ps", func() { _, ec, _ := podmanTest.RunLsContainer("test1") Expect(ec).To(Equal(0)) - result := podmanTest.Podman([]string{"ps", "-a", "--format", "\"table {{.ID}} {{.Image}} {{.Labels}}\""}) + result := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.ID}} {{.Image}} {{.Labels}}"}) result.WaitWithDefaultTimeout() + Expect(strings.Contains(result.OutputToStringArray()[0], "table")).To(BeFalse()) + Expect(strings.Contains(result.OutputToStringArray()[0], "ID")).To(BeTrue()) + Expect(strings.Contains(result.OutputToStringArray()[1], "alpine:latest")).To(BeTrue()) Expect(result.ExitCode()).To(Equal(0)) - Expect(result.IsJSONOutputValid()).To(BeTrue()) }) It("podman ps ancestor filter flag", func() { |