summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2019-01-10 11:11:46 -0800
committerGitHub <noreply@github.com>2019-01-10 11:11:46 -0800
commit6524041fb0ebfc35dafe3bb7bebbd4dfa27ba5e8 (patch)
treecf6e4191124ea1c44b9cadb504c0b2f5e6269a50
parente4525cf844535014923a2253e8531d92d9e556e5 (diff)
parent45fb935fe44a383ae14f16ab533281687d642c5e (diff)
downloadpodman-6524041fb0ebfc35dafe3bb7bebbd4dfa27ba5e8.tar.gz
podman-6524041fb0ebfc35dafe3bb7bebbd4dfa27ba5e8.tar.bz2
podman-6524041fb0ebfc35dafe3bb7bebbd4dfa27ba5e8.zip
Merge pull request #2119 from jwhonce/wip/python_podman
Move python code from contrib to it's own repo python-podman
-rw-r--r--.papr.sh12
-rw-r--r--.papr_prepare.sh4
-rw-r--r--Dockerfile9
-rw-r--r--Dockerfile.CentOS4
-rw-r--r--Dockerfile.Fedora4
-rw-r--r--Makefile29
-rw-r--r--contrib/python/.gitignore5
-rw-r--r--contrib/python/podman/.pylintrc564
-rw-r--r--contrib/python/podman/CHANGES.txt1
-rw-r--r--contrib/python/podman/LICENSE.txt13
-rw-r--r--contrib/python/podman/MANIFEST.in3
-rw-r--r--contrib/python/podman/Makefile40
-rw-r--r--contrib/python/podman/README.md44
-rw-r--r--contrib/python/podman/examples/eg_attach.py18
-rw-r--r--contrib/python/podman/examples/eg_containers_by_image.py16
-rw-r--r--contrib/python/podman/examples/eg_image_list.py10
-rw-r--r--contrib/python/podman/examples/eg_inspect_fedora.py16
-rw-r--r--contrib/python/podman/examples/eg_latest_containers.py19
-rw-r--r--contrib/python/podman/examples/eg_new_image.py32
-rwxr-xr-xcontrib/python/podman/examples/run_example.sh43
-rw-r--r--contrib/python/podman/podman/__init__.py29
-rw-r--r--contrib/python/podman/podman/client.py212
-rw-r--r--contrib/python/podman/podman/libs/__init__.py75
-rw-r--r--contrib/python/podman/podman/libs/_containers_attach.py79
-rw-r--r--contrib/python/podman/podman/libs/_containers_start.py82
-rw-r--r--contrib/python/podman/podman/libs/containers.py248
-rw-r--r--contrib/python/podman/podman/libs/errors.py77
-rw-r--r--contrib/python/podman/podman/libs/images.py164
-rw-r--r--contrib/python/podman/podman/libs/pods.py163
-rw-r--r--contrib/python/podman/podman/libs/system.py40
-rw-r--r--contrib/python/podman/podman/libs/tunnel.py190
-rw-r--r--contrib/python/podman/requirements.txt4
-rwxr-xr-xcontrib/python/podman/setup.py38
-rw-r--r--contrib/python/podman/test/__init__.py0
-rw-r--r--contrib/python/podman/test/podman_testcase.py112
-rw-r--r--contrib/python/podman/test/retry_decorator.py43
-rw-r--r--contrib/python/podman/test/test_client.py35
-rw-r--r--contrib/python/podman/test/test_containers.py244
-rw-r--r--contrib/python/podman/test/test_images.py174
-rw-r--r--contrib/python/podman/test/test_libs.py53
-rw-r--r--contrib/python/podman/test/test_pods_ctnrs.py66
-rw-r--r--contrib/python/podman/test/test_pods_no_ctnrs.py94
-rwxr-xr-xcontrib/python/podman/test/test_runner.sh156
-rw-r--r--contrib/python/podman/test/test_system.py63
-rw-r--r--contrib/python/podman/test/test_tunnel.py86
-rw-r--r--contrib/python/podman/tox.ini8
-rw-r--r--contrib/python/pypodman/.pylintrc564
-rw-r--r--contrib/python/pypodman/MANIFEST.in2
-rw-r--r--contrib/python/pypodman/Makefile39
-rw-r--r--contrib/python/pypodman/README.md34
-rw-r--r--contrib/python/pypodman/docs/man1/pypodman.1101
-rw-r--r--contrib/python/pypodman/pypodman/__init__.py0
-rw-r--r--contrib/python/pypodman/pypodman/lib/__init__.py43
-rw-r--r--contrib/python/pypodman/pypodman/lib/action_base.py79
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/__init__.py54
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/_create_args.py401
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/attach_action.py68
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/commit_action.py99
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/create_action.py55
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/export_action.py54
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/history_action.py79
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/images_action.py86
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/import_action.py69
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/info_action.py45
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/inspect_action.py89
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/kill_action.py49
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/logs_action.py61
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/mount_action.py78
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pause_action.py43
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/__init__.py24
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py76
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/inspect_parser.py43
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py57
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py49
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py94
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py54
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py50
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py45
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py44
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/top_parser.py35
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py50
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod_action.py36
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/port_action.py61
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/ps_action.py80
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pull_action.py46
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/push_action.py50
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/restart_action.py46
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/rm_action.py41
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/rmi_action.py40
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/run_action.py73
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/search_action.py160
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/start_action.py71
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/version_action.py35
-rw-r--r--contrib/python/pypodman/pypodman/lib/parser_actions.py247
-rw-r--r--contrib/python/pypodman/pypodman/lib/podman_parser.py255
-rw-r--r--contrib/python/pypodman/pypodman/lib/report.py87
-rwxr-xr-xcontrib/python/pypodman/pypodman/main.py81
-rw-r--r--contrib/python/pypodman/pypodman/test/test_report.py23
-rw-r--r--contrib/python/pypodman/requirements.txt5
-rwxr-xr-xcontrib/python/pypodman/setup.py45
-rw-r--r--contrib/spec/podman.spec.in52
-rw-r--r--test/install/Dockerfile.Centos2
-rw-r--r--test/install/Dockerfile.Fedora2
103 files changed, 5 insertions, 7767 deletions
diff --git a/.papr.sh b/.papr.sh
index 284326709..a42952824 100644
--- a/.papr.sh
+++ b/.papr.sh
@@ -25,14 +25,12 @@ pwd
# -t integration test
# -u unit test
# -v validate
-# -p run python tests
build=0
install=0
integrationtest=0
unittest=0
validate=0
-runpython=0
options=0
install_tools_made=0
@@ -44,9 +42,6 @@ while getopts "biptuv" opt; do
i) install=1
options=1
;;
- p) runpython=1
- options=1
- ;;
t) integrationtest=1
options=1
;;
@@ -124,18 +119,11 @@ if [ $install -eq 1 ]; then
make TAGS="${TAGS}" install.man PREFIX=/usr ETCDIR=/etc
make TAGS="${TAGS}" install.cni PREFIX=/usr ETCDIR=/etc
make TAGS="${TAGS}" install.systemd PREFIX=/usr ETCDIR=/etc
- if [ $runpython -eq 1 ]; then
- make TAGS="${TAGS}" install.python PREFIX=/usr ETCDIR=/etc
- fi
-
fi
# Run integration tests
if [ $integrationtest -eq 1 ]; then
make TAGS="${TAGS}" test-binaries
make varlink_generate GOPATH=/go
- if [ $runpython -eq 1 ]; then
- make clientintegration GOPATH=/go
- fi
make ginkgo GOPATH=/go $INTEGRATION_TEST_ENVS
fi
diff --git a/.papr_prepare.sh b/.papr_prepare.sh
index 5d7d21530..b93f7b91f 100644
--- a/.papr_prepare.sh
+++ b/.papr_prepare.sh
@@ -4,10 +4,8 @@ set -xeuo pipefail
DIST=${DIST:=Fedora}
CONTAINER_RUNTIME=${CONTAINER_RUNTIME:=docker}
IMAGE=fedorapodmanbuild
-PYTHON=python3
if [[ ${DIST} != "Fedora" ]]; then
IMAGE=centospodmanbuild
- PYTHON=python
fi
# Since CRIU 3.11 has been pushed to Fedora 28 the checkpoint/restore
@@ -21,4 +19,4 @@ modprobe iptable_nat || :
${CONTAINER_RUNTIME} build -t ${IMAGE} -f Dockerfile.${DIST} . 2>build.log
# Run the tests
-${CONTAINER_RUNTIME} run --rm --privileged --net=host -v $PWD:/go/src/github.com/containers/libpod:Z --workdir /go/src/github.com/containers/libpod -e CGROUP_MANAGER=cgroupfs -e PYTHON=$PYTHON -e STORAGE_OPTIONS="--storage-driver=vfs" -e CRIO_ROOT="/go/src/github.com/containers/libpod" -e PODMAN_BINARY="/usr/bin/podman" -e CONMON_BINARY="/usr/libexec/podman/conmon" -e DIST=$DIST -e CONTAINER_RUNTIME=$CONTAINER_RUNTIME $IMAGE sh ./.papr.sh -b -i -t
+${CONTAINER_RUNTIME} run --rm --privileged --net=host -v $PWD:/go/src/github.com/containers/libpod:Z --workdir /go/src/github.com/containers/libpod -e CGROUP_MANAGER=cgroupfs -e STORAGE_OPTIONS="--storage-driver=vfs" -e CRIO_ROOT="/go/src/github.com/containers/libpod" -e PODMAN_BINARY="/usr/bin/podman" -e CONMON_BINARY="/usr/libexec/podman/conmon" -e DIST=$DIST -e CONTAINER_RUNTIME=$CONTAINER_RUNTIME $IMAGE sh ./.papr.sh -b -i -t
diff --git a/Dockerfile b/Dockerfile
index c227207bd..59b5d5da3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -27,7 +27,6 @@ RUN apt-get update && apt-get install -y \
libudev-dev \
protobuf-c-compiler \
protobuf-compiler \
- python-minimal \
libglib2.0-dev \
libapparmor-dev \
btrfs-tools \
@@ -37,11 +36,6 @@ RUN apt-get update && apt-get install -y \
liblzma-dev \
netcat \
socat \
- python3-pip \
- python3-dateutil \
- python3-setuptools \
- python3-psutil \
- python3-pytoml \
lsof \
xz-utils \
--no-install-recommends \
@@ -129,9 +123,6 @@ COPY cni/87-podman-bridge.conflist /etc/cni/net.d/87-podman-bridge.conflist
# Make sure we have some policy for pulling images
RUN mkdir -p /etc/containers && curl https://raw.githubusercontent.com/projectatomic/registries/master/registries.fedora -o /etc/containers/registries.conf
-# Install python3 varlink module from pypi
-RUN pip3 install varlink
-
COPY test/policy.json /etc/containers/policy.json
COPY test/redhat_sigstore.yaml /etc/containers/registries.d/registry.access.redhat.com.yaml
diff --git a/Dockerfile.CentOS b/Dockerfile.CentOS
index 3e14e59db..be4ae3eaf 100644
--- a/Dockerfile.CentOS
+++ b/Dockerfile.CentOS
@@ -19,10 +19,6 @@ RUN yum -y install btrfs-progs-devel \
runc \
make \
ostree-devel \
- python \
- python3-dateutil \
- python3-psutil \
- python3-pytoml \
lsof \
which\
golang-github-cpuguy83-go-md2man \
diff --git a/Dockerfile.Fedora b/Dockerfile.Fedora
index 2080b597b..aeee9c3cf 100644
--- a/Dockerfile.Fedora
+++ b/Dockerfile.Fedora
@@ -20,10 +20,6 @@ RUN dnf -y install btrfs-progs-devel \
runc \
make \
ostree-devel \
- python \
- python3-dateutil \
- python3-psutil \
- python3-pytoml \
lsof \
which\
golang-github-cpuguy83-go-md2man \
diff --git a/Makefile b/Makefile
index 93b9fcd58..c672fd947 100644
--- a/Makefile
+++ b/Makefile
@@ -26,8 +26,6 @@ ifneq (,$(findstring varlink,$(BUILDTAGS)))
endif
CONTAINER_RUNTIME := $(shell command -v podman 2> /dev/null || echo docker)
-HAS_PYTHON3 := $(shell command -v python3 2>/dev/null)
-
BASHINSTALLDIR=${PREFIX}/share/bash-completion/completions
OCIUMOUNTINSTALLDIR=$(PREFIX)/share/oci-umount/oci-umount.d
@@ -88,9 +86,6 @@ endif
lint: .gopathok varlink_generate
@echo "checking lint"
@./.tool/lint
- # Not ready
- # @$(MAKE) -C contrib/python/podman lint
- # @$(MAKE) -C contrib/python/pypodman lint
gofmt:
find . -name '*.go' ! -path './vendor/*' -exec gofmt -s -w {} \+
@@ -122,12 +117,6 @@ bin/podman.cross.%: .gopathok
GOARCH="$${TARGET##*.}" \
$(GO) build -ldflags '$(LDFLAGS_PODMAN)' -tags '$(BUILDTAGS_CROSS)' -o "$@" $(PROJECT)/cmd/podman
-python:
-ifdef HAS_PYTHON3
- $(MAKE) -C contrib/python/podman python-podman
- $(MAKE) -C contrib/python/pypodman python-pypodman
-endif
-
clean:
rm -rf \
.gopathok \
@@ -147,8 +136,6 @@ clean:
$(MANPAGES) ||:
find . -name \*~ -delete
find . -name \#\* -delete
- $(MAKE) -C contrib/python/podman clean
- $(MAKE) -C contrib/python/pypodman clean
libpodimage:
${CONTAINER_RUNTIME} build -t ${LIBPOD_IMAGE} .
@@ -181,7 +168,7 @@ localunit: test/goecho/goecho varlink_generate
ginkgo:
ginkgo -v -tags "$(BUILDTAGS)" -cover -flakeAttempts 3 -progress -trace -noColor test/e2e/.
-localintegration: varlink_generate test-binaries clientintegration ginkgo
+localintegration: varlink_generate test-binaries ginkgo
localsystem: .install.ginkgo .install.gomega
ginkgo -v -noColor test/system/
@@ -189,10 +176,6 @@ localsystem: .install.ginkgo .install.gomega
system.test-binary: .install.ginkgo .install.gomega
$(GO) test -c ./test/system
-clientintegration:
- $(MAKE) -C contrib/python/podman integration
- $(MAKE) -C contrib/python/pypodman integration
-
perftest:
$ cd contrib/perftest;go build
@@ -230,7 +213,7 @@ changelog:
$(shell cat $(TMPFILE) >> changelog.txt)
$(shell rm $(TMPFILE))
-install: .gopathok install.bin install.man install.cni install.systemd install.python
+install: .gopathok install.bin install.man install.cni install.systemd
install.bin:
install ${SELINUXOPT} -d -m 755 $(BINDIR)
@@ -268,10 +251,6 @@ install.systemd:
install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.service ${SYSTEMDDIR}/io.podman.service
install ${SELINUXOPT} -m 644 contrib/varlink/podman.conf ${TMPFILESDIR}/podman.conf
-install.python:
- $(MAKE) DESTDIR=${DESTDIR} -C contrib/python/podman install
- $(MAKE) DESTDIR=${DESTDIR} -C contrib/python/pypodman install
-
uninstall:
for i in $(filter %.1,$(MANPAGES)); do \
rm -f $(MANDIR)/man1/$$(basename $${i}); \
@@ -279,8 +258,6 @@ uninstall:
for i in $(filter %.5,$(MANPAGES)); do \
rm -f $(MANDIR)/man5/$$(basename $${i}); \
done
- $(MAKE) -C contrib/python/pypodman uninstall
- $(MAKE) -C contrib/python/podman uninstall
.PHONY: .gitvalidation
.gitvalidation: .gopathok
@@ -382,5 +359,3 @@ build-all-new-commits:
changelog \
validate \
install.libseccomp.sudo \
- python \
- clientintegration
diff --git a/contrib/python/.gitignore b/contrib/python/.gitignore
deleted file mode 100644
index a3903c542..000000000
--- a/contrib/python/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-build
-dist
-*.egg-info
-*.pyc
-__pycache__
diff --git a/contrib/python/podman/.pylintrc b/contrib/python/podman/.pylintrc
deleted file mode 100644
index a5628a6cf..000000000
--- a/contrib/python/podman/.pylintrc
+++ /dev/null
@@ -1,564 +0,0 @@
-[MASTER]
-
-# A comma-separated list of package or module names from where C extensions may
-# be loaded. Extensions are loading into the active Python interpreter and may
-# run arbitrary code.
-extension-pkg-whitelist=
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=CVS
-
-# Add files or directories matching the regex patterns to the blacklist. The
-# regex matches against base names, not paths.
-ignore-patterns=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
-# number of processors available to use.
-jobs=0
-
-# Control the amount of potential inferred values when inferring a single
-# object. This can help the performance when dealing with large functions or
-# complex, nested conditions.
-limit-inference-results=100
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-# Pickle collected data for later comparisons.
-persistent=yes
-
-# Specify a configuration file.
-#rcfile=
-
-# When enabled, pylint would attempt to guess common misconfiguration and emit
-# user-friendly hints instead of false-positive error messages.
-suggestion-mode=yes
-
-# Allow loading of arbitrary C extensions. Extensions are imported into the
-# active Python interpreter and may run arbitrary code.
-unsafe-load-any-extension=no
-
-
-[MESSAGES CONTROL]
-
-# Only show warnings with the listed confidence levels. Leave empty to show
-# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
-confidence=
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifiers separated by comma (,) or put this
-# option multiple times (only on the command line, not in the configuration
-# file where it should appear only once). You can also use "--disable=all" to
-# disable everything first and then reenable specific checks. For example, if
-# you want to run only the similarities checker, you can use "--disable=all
-# --enable=similarities". If you want to run only the classes checker, but have
-# no Warning level messages displayed, use "--disable=all --enable=classes
-# --disable=W".
-disable=print-statement,
- parameter-unpacking,
- unpacking-in-except,
- old-raise-syntax,
- backtick,
- long-suffix,
- old-ne-operator,
- old-octal-literal,
- import-star-module-level,
- non-ascii-bytes-literal,
- raw-checker-failed,
- bad-inline-option,
- locally-disabled,
- locally-enabled,
- file-ignored,
- suppressed-message,
- useless-suppression,
- deprecated-pragma,
- use-symbolic-message-instead,
- apply-builtin,
- basestring-builtin,
- buffer-builtin,
- cmp-builtin,
- coerce-builtin,
- execfile-builtin,
- file-builtin,
- long-builtin,
- raw_input-builtin,
- reduce-builtin,
- standarderror-builtin,
- unicode-builtin,
- xrange-builtin,
- coerce-method,
- delslice-method,
- getslice-method,
- setslice-method,
- no-absolute-import,
- old-division,
- dict-iter-method,
- dict-view-method,
- next-method-called,
- metaclass-assignment,
- indexing-exception,
- raising-string,
- reload-builtin,
- oct-method,
- hex-method,
- nonzero-method,
- cmp-method,
- input-builtin,
- round-builtin,
- intern-builtin,
- unichr-builtin,
- map-builtin-not-iterating,
- zip-builtin-not-iterating,
- range-builtin-not-iterating,
- filter-builtin-not-iterating,
- using-cmp-argument,
- eq-without-hash,
- div-method,
- idiv-method,
- rdiv-method,
- exception-message-attribute,
- invalid-str-codec,
- sys-max-int,
- bad-python3-import,
- deprecated-string-function,
- deprecated-str-translate-call,
- deprecated-itertools-function,
- deprecated-types-field,
- next-method-defined,
- dict-items-not-iterating,
- dict-keys-not-iterating,
- dict-values-not-iterating,
- deprecated-operator-function,
- deprecated-urllib-function,
- xreadlines-attribute,
- deprecated-sys-function,
- exception-escape,
- comprehension-escape
-
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time (only on the command line, not in the configuration file where
-# it should appear only once). See also the "--disable" option for examples.
-enable=c-extension-no-member
-
-
-[REPORTS]
-
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Template used to display messages. This is a python new-style format string
-# used to format the message information. See doc for all details.
-#msg-template=
-
-# Set the output format. Available formats are text, parseable, colorized, json
-# and msvs (visual studio). You can also give a reporter class, e.g.
-# mypackage.mymodule.MyReporterClass.
-output-format=text
-
-# Tells whether to display a full report or only the messages.
-reports=no
-
-# Activate the evaluation score.
-score=yes
-
-
-[REFACTORING]
-
-# Maximum number of nested blocks for function / method body
-max-nested-blocks=5
-
-# Complete name of functions that never returns. When checking for
-# inconsistent-return-statements if a never returning function is called then
-# it will be considered as an explicit return statement and no message will be
-# printed.
-never-returning-functions=sys.exit
-
-
-[TYPECHECK]
-
-# List of decorators that produce context managers, such as
-# contextlib.contextmanager. Add to this list to register other decorators that
-# produce valid context managers.
-contextmanager-decorators=contextlib.contextmanager
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E1101 when accessed. Python regular
-# expressions are accepted.
-generated-members=
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# Tells whether to warn about missing members when the owner of the attribute
-# is inferred to be None.
-ignore-none=yes
-
-# This flag controls whether pylint should warn about no-member and similar
-# checks whenever an opaque object is returned when inferring. The inference
-# can return multiple potential results while evaluating a Python object, but
-# some branches might not be evaluated, which results in partial inference. In
-# that case, it might be useful to still emit no-member and other checks for
-# the rest of the inferred objects.
-ignore-on-opaque-inference=yes
-
-# List of class names for which member attributes should not be checked (useful
-# for classes with dynamically set attributes). This supports the use of
-# qualified names.
-ignored-classes=optparse.Values,thread._local,_thread._local
-
-# List of module names for which member attributes should not be checked
-# (useful for modules/projects where namespaces are manipulated during runtime
-# and thus existing member attributes cannot be deduced by static analysis. It
-# supports qualified module names, as well as Unix pattern matching.
-ignored-modules=
-
-# Show a hint with possible names when a member name was not found. The aspect
-# of finding the hint is based on edit distance.
-missing-member-hint=yes
-
-# The minimum edit distance a name should have in order to be considered a
-# similar match for a missing member name.
-missing-member-hint-distance=1
-
-# The total number of similar names that should be taken in consideration when
-# showing a hint for a missing member.
-missing-member-max-choices=1
-
-
-[SPELLING]
-
-# Limits count of emitted suggestions for spelling mistakes.
-max-spelling-suggestions=4
-
-# Spelling dictionary name. Available dictionaries: none. To make it working
-# install python-enchant package..
-spelling-dict=
-
-# List of comma separated words that should not be checked.
-spelling-ignore-words=
-
-# A path to a file that contains private dictionary; one word per line.
-spelling-private-dict-file=
-
-# Tells whether to store unknown words to indicated private dictionary in
-# --spelling-private-dict-file option instead of raising a message.
-spelling-store-unknown-words=no
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,
- XXX,
- TODO
-
-
-[FORMAT]
-
-# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
-expected-line-ending-format=
-
-# Regexp for a line that is allowed to be longer than the limit.
-ignore-long-lines=^\s*(# )?<?https?://\S+>?$
-
-# Number of spaces of indent required inside a hanging or continued line.
-indent-after-paren=4
-
-# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
-# tab).
-indent-string=' '
-
-# Maximum number of characters on a single line.
-max-line-length=100
-
-# Maximum number of lines in a module.
-max-module-lines=1000
-
-# List of optional constructs for which whitespace checking is disabled. `dict-
-# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
-# `trailing-comma` allows a space between comma and closing bracket: (a, ).
-# `empty-line` allows space-only lines.
-no-space-check=trailing-comma,
- dict-separator
-
-# Allow the body of a class to be on the same line as the declaration if body
-# contains single statement.
-single-line-class-stmt=no
-
-# Allow the body of an if to be on the same line as the test if there is no
-# else.
-single-line-if-stmt=no
-
-
-[BASIC]
-
-# Naming style matching correct argument names.
-#argument-naming-style=snake_case
-
-# Regular expression matching correct argument names. Overrides argument-
-# naming-style.
-argument-rgx=[a-z_][a-z0-9_]{1,30}$
-argument-name-hint=[a-z_][a-z0-9_]{1,30}$
-
-# Naming style matching correct attribute names.
-attr-naming-style=snake_case
-
-# Regular expression matching correct attribute names. Overrides attr-naming-
-# style.
-#attr-rgx=
-
-# Bad variable names which should always be refused, separated by a comma.
-bad-names=foo,
- bar,
- baz,
- toto,
- tutu,
- tata
-
-# Naming style matching correct class attribute names.
-class-attribute-naming-style=any
-
-# Regular expression matching correct class attribute names. Overrides class-
-# attribute-naming-style.
-#class-attribute-rgx=
-
-# Naming style matching correct class names.
-class-naming-style=PascalCase
-
-# Regular expression matching correct class names. Overrides class-naming-
-# style.
-#class-rgx=
-
-# Naming style matching correct constant names.
-const-naming-style=UPPER_CASE
-
-# Regular expression matching correct constant names. Overrides const-naming-
-# style.
-#const-rgx=
-
-# Minimum line length for functions/classes that require docstrings, shorter
-# ones are exempt.
-docstring-min-length=-1
-
-# Naming style matching correct function names.
-function-naming-style=snake_case
-
-# Regular expression matching correct function names. Overrides function-
-# naming-style.
-#function-rgx=
-
-# Good variable names which should always be accepted, separated by a comma.
-good-names=c,
- e,
- i,
- j,
- k,
- r,
- v,
- ex,
- Run,
- _
-
-# Include a hint for the correct naming format with invalid-name.
-include-naming-hint=no
-
-# Naming style matching correct inline iteration names.
-inlinevar-naming-style=any
-
-# Regular expression matching correct inline iteration names. Overrides
-# inlinevar-naming-style.
-#inlinevar-rgx=
-
-# Naming style matching correct method names.
-method-naming-style=snake_case
-
-# Regular expression matching correct method names. Overrides method-naming-
-# style.
-#method-rgx=
-
-# Naming style matching correct module names.
-module-naming-style=snake_case
-
-# Regular expression matching correct module names. Overrides module-naming-
-# style.
-#module-rgx=
-
-# Colon-delimited sets of names that determine each other's naming style when
-# the name regexes allow several styles.
-name-group=
-
-# Regular expression which should only match function or class names that do
-# not require a docstring.
-no-docstring-rgx=^_
-
-# List of decorators that produce properties, such as abc.abstractproperty. Add
-# to this list to register other decorators that produce valid properties.
-# These decorators are taken in consideration only for invalid-name.
-property-classes=abc.abstractproperty
-
-# Naming style matching correct variable names.
-#variable-naming-style=snake_case
-
-# Regular expression matching correct variable names. Overrides variable-
-# naming-style.
-variable-rgx=[a-z_][a-z0-9_]{2,30}$
-variable-name-hint=[a-z_][a-z0-9_]{2,30}$
-
-[SIMILARITIES]
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-# Ignore imports when computing similarities.
-ignore-imports=no
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-
-[VARIABLES]
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-# Tells whether unused global variables should be treated as a violation.
-allow-global-unused-variables=yes
-
-# List of strings which can identify a callback function by name. A callback
-# name must start or end with one of those strings.
-callbacks=cb_,
- _cb
-
-# A regular expression matching the name of dummy variables (i.e. expected to
-# not be used).
-dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore.
-ignored-argument-names=_.*|^ignored_|^unused_
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# List of qualified module names which can have objects that can redefine
-# builtins.
-redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
-
-
-[LOGGING]
-
-# Logging modules to check that the string format arguments are in logging
-# function parameter format.
-logging-modules=logging
-
-
-[IMPORTS]
-
-# Allow wildcard imports from modules that define __all__.
-allow-wildcard-with-all=no
-
-# Analyse import fallback blocks. This can be used to support both Python 2 and
-# 3 compatible code, which means that the block might have code that exists
-# only in one or another interpreter, leading to false positives when analysed.
-analyse-fallback-blocks=no
-
-# Deprecated modules which should not be used, separated by a comma.
-deprecated-modules=optparse,tkinter.tix
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled).
-ext-import-graph=
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled).
-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled).
-int-import-graph=
-
-# Force import order to recognize a module as part of the standard
-# compatibility libraries.
-known-standard-library=
-
-# Force import order to recognize a module as part of a third party library.
-known-third-party=enchant
-
-
-[DESIGN]
-
-# Support argparse.Action constructor API
-# Maximum number of arguments for function / method.
-max-args=12
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=7
-
-# Maximum number of boolean expressions in an if statement.
-max-bool-expr=5
-
-# Maximum number of branch for function / method body.
-max-branches=12
-
-# Maximum number of locals for function / method body.
-max-locals=15
-
-# Maximum number of parents for a class (see R0901).
-max-parents=10
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=20
-
-# Maximum number of return / yield for function / method body.
-max-returns=6
-
-# Maximum number of statements in function / method body.
-max-statements=50
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=2
-
-
-[CLASSES]
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,
- __new__,
- setUp
-
-# List of member names, which should be excluded from the protected access
-# warning.
-exclude-protected=_asdict,
- _fields,
- _replace,
- _source,
- _make
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-# List of valid names for the first argument in a metaclass class method.
-valid-metaclass-classmethod-first-arg=cls
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception".
-overgeneral-exceptions=Exception
diff --git a/contrib/python/podman/CHANGES.txt b/contrib/python/podman/CHANGES.txt
deleted file mode 100644
index 2bac1c867..000000000
--- a/contrib/python/podman/CHANGES.txt
+++ /dev/null
@@ -1 +0,0 @@
-v0.1.0, 2018-05-11 -- Initial release.
diff --git a/contrib/python/podman/LICENSE.txt b/contrib/python/podman/LICENSE.txt
deleted file mode 100644
index decfce56d..000000000
--- a/contrib/python/podman/LICENSE.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright 2018 Red Hat, Inc
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/contrib/python/podman/MANIFEST.in b/contrib/python/podman/MANIFEST.in
deleted file mode 100644
index a5897de50..000000000
--- a/contrib/python/podman/MANIFEST.in
+++ /dev/null
@@ -1,3 +0,0 @@
-prune test/
-include README.md
-include requirements.txt
diff --git a/contrib/python/podman/Makefile b/contrib/python/podman/Makefile
deleted file mode 100644
index 0cbfe2fb3..000000000
--- a/contrib/python/podman/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-PYTHON ?= $(shell command -v python3 2>/dev/null || command -v python)
-DESTDIR ?= /
-PODMAN_VERSION ?= '0.11.1.1'
-
-.PHONY: python-podman
-python-podman:
- PODMAN_VERSION=$(PODMAN_VERSION) \
- $(PYTHON) setup.py sdist bdist
-
-.PHONY: lint
-lint:
- $(PYTHON) -m pylint podman
-
-.PHONY: integration
-integration:
- test/test_runner.sh -v
-
-.PHONY: install
-install:
- PODMAN_VERSION=$(PODMAN_VERSION) \
- $(PYTHON) setup.py install --root ${DESTDIR}
-
-.PHONY: upload
-upload:
- PODMAN_VERSION=$(PODMAN_VERSION) $(PYTHON) setup.py sdist bdist_wheel
- twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
-
-.PHONY: clobber
-clobber: uninstall clean
-
-.PHONY: uninstall
-uninstall:
- $(PYTHON) -m pip uninstall --yes podman ||:
-
-.PHONY: clean
-clean:
- rm -rf podman.egg-info dist
- find . -depth -name __pycache__ -exec rm -rf {} \;
- find . -depth -name \*.pyc -exec rm -f {} \;
- $(PYTHON) ./setup.py clean --all
diff --git a/contrib/python/podman/README.md b/contrib/python/podman/README.md
deleted file mode 100644
index 3254064b0..000000000
--- a/contrib/python/podman/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# podman - pythonic library for working with varlink interface to Podman
-
-## Status: Active Development
-
-See [libpod](https://github.com/containers/libpod)
-
-## Releases
-
-To build the podman egg and install as user:
-
-```sh
-cd ~/libpod/contrib/python/podman
-python3 setup.py clean -a && python3 setup.py sdist bdist
-python3 setup.py install --user
-```
-
-## Code snippets/examples:
-
-### Show images in storage
-
-```python
-import podman
-
-with podman.Client() as client:
- list(map(print, client.images.list()))
-```
-
-### Show containers created since midnight
-
-```python
-from datetime import datetime, time, timezone
-
-import podman
-
-midnight = datetime.combine(datetime.today(), time.min, tzinfo=timezone.utc)
-
-with podman.Client() as client:
- for c in client.containers.list():
- created_at = podman.datetime_parse(c.createdat)
-
- if created_at > midnight:
- print('Container {}: image: {} created at: {}'.format(
- c.id[:12], c.image[:32], podman.datetime_format(created_at)))
-```
diff --git a/contrib/python/podman/examples/eg_attach.py b/contrib/python/podman/examples/eg_attach.py
deleted file mode 100644
index f5070dc53..000000000
--- a/contrib/python/podman/examples/eg_attach.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python3
-"""Example: Run top on Alpine container."""
-
-import podman
-
-print('{}\n'.format(__doc__))
-
-with podman.Client() as client:
- id = client.images.pull('alpine:latest')
- img = client.images.get(id)
- cntr = img.create(detach=True, tty=True, command=['/usr/bin/top'])
- cntr.attach(eot=4)
-
- try:
- cntr.start()
- print()
- except (BrokenPipeError, KeyboardInterrupt):
- print('\nContainer disconnected.')
diff --git a/contrib/python/podman/examples/eg_containers_by_image.py b/contrib/python/podman/examples/eg_containers_by_image.py
deleted file mode 100644
index bf4fdebf1..000000000
--- a/contrib/python/podman/examples/eg_containers_by_image.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python3
-"""Example: Show containers grouped by image id."""
-
-from itertools import groupby
-
-import podman
-
-print('{}\n'.format(__doc__))
-
-with podman.Client() as client:
- ctnrs = sorted(client.containers.list(), key=lambda k: k.imageid)
- for key, grp in groupby(ctnrs, key=lambda k: k.imageid):
- print('Image: {}'.format(key))
- for c in grp:
- print(' : container: {} created at: {}'.format(
- c.id[:12], podman.datetime_format(c.createdat)))
diff --git a/contrib/python/podman/examples/eg_image_list.py b/contrib/python/podman/examples/eg_image_list.py
deleted file mode 100644
index ef31fd708..000000000
--- a/contrib/python/podman/examples/eg_image_list.py
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env python3
-"""Example: Show all images on system."""
-
-import podman
-
-print('{}\n'.format(__doc__))
-
-with podman.Client() as client:
- for img in client.images.list():
- print(img)
diff --git a/contrib/python/podman/examples/eg_inspect_fedora.py b/contrib/python/podman/examples/eg_inspect_fedora.py
deleted file mode 100644
index b5bbba46d..000000000
--- a/contrib/python/podman/examples/eg_inspect_fedora.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python3
-"""Example: Pull Fedora and inspect image and container."""
-
-import podman
-
-print('{}\n'.format(__doc__))
-
-with podman.Client() as client:
- id = client.images.pull('registry.fedoraproject.org/fedora:28')
- img = client.images.get(id)
- print(img.inspect())
-
- cntr = img.create()
- print(cntr.inspect())
-
- cntr.remove()
diff --git a/contrib/python/podman/examples/eg_latest_containers.py b/contrib/python/podman/examples/eg_latest_containers.py
deleted file mode 100644
index 446f670dd..000000000
--- a/contrib/python/podman/examples/eg_latest_containers.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-"""Example: Show all containers created since midnight."""
-
-from datetime import datetime, time, timezone
-
-import podman
-
-print('{}\n'.format(__doc__))
-
-
-midnight = datetime.combine(datetime.today(), time.min, tzinfo=timezone.utc)
-
-with podman.Client() as client:
- for c in client.containers.list():
- created_at = podman.datetime_parse(c.createdat)
-
- if created_at > midnight:
- print('{}: image: {} createdAt: {}'.format(
- c.id[:12], c.image[:32], podman.datetime_format(created_at)))
diff --git a/contrib/python/podman/examples/eg_new_image.py b/contrib/python/podman/examples/eg_new_image.py
deleted file mode 100644
index 21e076dcb..000000000
--- a/contrib/python/podman/examples/eg_new_image.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-"""Example: Create new image from container."""
-
-import sys
-
-import podman
-
-
-def print_history(details):
- """Format history data from an image, in a table."""
- for i, r in enumerate(details):
- print(
- '{}: {} {} {}'.format(i, r.id[:12],
- podman.datetime_format(r.created), r.tags),
- sep='\n')
- print("-" * 25)
-
-
-print('{}\n'.format(__doc__))
-
-with podman.Client() as client:
- ctnr = next(
- (c for c in client.containers.list() if 'alpine' in c['image']), None)
-
- if ctnr:
- print_history(client.images.get(ctnr.imageid).history())
-
- # Make changes as we save the container to a new image
- id = ctnr.commit('alpine-ash', changes=['CMD=/bin/ash'])
- print_history(client.images.get(id).history())
- else:
- print('Unable to find "alpine" container.', file=sys.stderr)
diff --git a/contrib/python/podman/examples/run_example.sh b/contrib/python/podman/examples/run_example.sh
deleted file mode 100755
index d81ddf456..000000000
--- a/contrib/python/podman/examples/run_example.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-
-export PYTHONPATH=..
-
-function examples {
- for file in $@; do
- python3 -c "import ast; f=open('"${file}"'); t=ast.parse(f.read()); print(ast.get_docstring(t) + ' -- "${file}"')"
- done
-}
-
-while getopts "lh" arg; do
- case $arg in
- l ) examples $(ls eg_*.py); exit 0 ;;
- h ) echo 1>&2 $0 [-l] [-h] filename ; exit 2 ;;
- esac
-done
-shift $((OPTIND-1))
-
-# podman needs to play some games with resources
-if [[ $(id -u) != 0 ]]; then
- echo 1>&2 $0 must be run as root.
- exit 2
-fi
-
-if ! systemctl --quiet is-active io.podman.socket; then
- echo 1>&2 'podman is not running. systemctl enable --now io.podman.socket'
- exit 1
-fi
-
-function cleanup {
- podman rm $1 >/dev/null 2>&1
-}
-
-# Setup storage with an image and container
-podman pull alpine:latest >/tmp/podman.output 2>&1
-CTNR=$(podman create alpine)
-trap "cleanup $CTNR" EXIT
-
-if [[ -f $1 ]]; then
- python3 $1
-else
- python3 $1.py
-fi
diff --git a/contrib/python/podman/podman/__init__.py b/contrib/python/podman/podman/__init__.py
deleted file mode 100644
index 1cdb72773..000000000
--- a/contrib/python/podman/podman/__init__.py
+++ /dev/null
@@ -1,29 +0,0 @@
-"""A client for communicating with a Podman server."""
-import pkg_resources
-
-from .client import Client
-from .libs import FoldedString, datetime_format, datetime_parse
-from .libs.errors import (ContainerNotFound, ErrorOccurred, ImageNotFound,
- NoContainerRunning, NoContainersInPod,
- PodContainerError, PodmanError, PodNotFound)
-
-assert FoldedString
-
-try:
- __version__ = pkg_resources.get_distribution('podman').version
-except Exception: # pylint: disable=broad-except
- __version__ = '0.0.0'
-
-__all__ = [
- 'Client',
- 'ContainerNotFound',
- 'datetime_format',
- 'datetime_parse',
- 'ErrorOccurred',
- 'ImageNotFound',
- 'NoContainerRunning',
- 'NoContainersInPod',
- 'PodContainerError',
- 'PodmanError',
- 'PodNotFound',
-]
diff --git a/contrib/python/podman/podman/client.py b/contrib/python/podman/podman/client.py
deleted file mode 100644
index ad603166e..000000000
--- a/contrib/python/podman/podman/client.py
+++ /dev/null
@@ -1,212 +0,0 @@
-"""A client for communicating with a Podman varlink service."""
-import errno
-import logging
-import os
-from urllib.parse import urlparse
-
-from varlink import Client as VarlinkClient
-from varlink import VarlinkError
-
-from .libs import cached_property
-from .libs.containers import Containers
-from .libs.errors import error_factory
-from .libs.images import Images
-from .libs.system import System
-from .libs.tunnel import Context, Portal, Tunnel
-from .libs.pods import Pods
-
-
-class BaseClient():
- """Context manager for API workers to access varlink."""
-
- def __init__(self, context):
- """Construct Client."""
- self._client = None
- self._iface = None
- self._context = context
-
- def __call__(self):
- """Support being called for old API."""
- return self
-
- @classmethod
- def factory(cls,
- uri=None,
- interface='io.podman',
- *args,
- **kwargs):
- """Construct a Client based on input."""
- log_level = os.environ.get('LOG_LEVEL')
- if log_level is not None:
- logging.basicConfig(level=logging.getLevelName(log_level.upper()))
-
- if uri is None:
- raise ValueError('uri is required and cannot be None')
- if interface is None:
- raise ValueError('interface is required and cannot be None')
-
- unsupported = set(kwargs.keys()).difference(
- ('uri', 'interface', 'remote_uri', 'identity_file'))
- if unsupported:
- raise ValueError('Unknown keyword arguments: {}'.format(
- ', '.join(unsupported)))
-
- local_path = urlparse(uri).path
- if local_path == '':
- raise ValueError('path is required for uri,'
- ' expected format "unix://path_to_socket"')
-
- if kwargs.get('remote_uri') is None:
- return LocalClient(Context(uri, interface))
-
- required = ('{} is required, expected format'
- ' "ssh://user@hostname[:port]/path_to_socket".')
-
- # Remote access requires the full tuple of information
- if kwargs.get('remote_uri') is None:
- raise ValueError(required.format('remote_uri'))
-
- remote = urlparse(kwargs['remote_uri'])
- if remote.username is None:
- raise ValueError(required.format('username'))
- if remote.path == '':
- raise ValueError(required.format('path'))
- if remote.hostname is None:
- raise ValueError(required.format('hostname'))
-
- return RemoteClient(
- Context(
- uri,
- interface,
- local_path,
- remote.path,
- remote.username,
- remote.hostname,
- remote.port,
- kwargs.get('identity_file'),
- ))
-
-
-class LocalClient(BaseClient):
- """Context manager for API workers to access varlink."""
-
- def __enter__(self):
- """Enter context for LocalClient."""
- self._client = VarlinkClient(address=self._context.uri)
- self._iface = self._client.open(self._context.interface)
- return self._iface
-
- def __exit__(self, e_type, e, e_traceback):
- """Cleanup context for LocalClient."""
- if hasattr(self._client, 'close'):
- self._client.close()
- self._iface.close()
-
- if isinstance(e, VarlinkError):
- raise error_factory(e)
-
-
-class RemoteClient(BaseClient):
- """Context manager for API workers to access remote varlink."""
-
- def __init__(self, context):
- """Construct RemoteCLient."""
- super().__init__(context)
- self._portal = Portal()
-
- def __enter__(self):
- """Context manager for API workers to access varlink."""
- tunnel = self._portal.get(self._context.uri)
- if tunnel is None:
- tunnel = Tunnel(self._context).bore()
- self._portal[self._context.uri] = tunnel
-
- try:
- self._client = VarlinkClient(address=self._context.uri)
- self._iface = self._client.open(self._context.interface)
- return self._iface
- except Exception:
- tunnel.close()
- raise
-
- def __exit__(self, e_type, e, e_traceback):
- """Cleanup context for RemoteClient."""
- if hasattr(self._client, 'close'):
- self._client.close()
- self._iface.close()
-
- # set timer to shutdown ssh tunnel
- # self._portal.get(self._context.uri).close()
- if isinstance(e, VarlinkError):
- raise error_factory(e)
-
-
-class Client():
- """A client for communicating with a Podman varlink service.
-
- Example:
-
- >>> import podman
- >>> c = podman.Client()
- >>> c.system.versions
-
- Example remote podman:
-
- >>> import podman
- >>> c = podman.Client(uri='unix:/tmp/podman.sock',
- remote_uri='ssh://user@host/run/podman/io.podman',
- identity_file='~/.ssh/id_rsa')
- """
-
- def __init__(self,
- uri='unix:/run/podman/io.podman',
- interface='io.podman',
- **kwargs):
- """Construct a podman varlink Client.
-
- uri from default systemd unit file.
- interface from io.podman.varlink, do not change unless
- you are a varlink guru.
- """
- self._client = BaseClient.factory(uri, interface, **kwargs)
-
- address = "{}-{}".format(uri, interface)
- # Quick validation of connection data provided
- try:
- if not System(self._client).ping():
- raise ConnectionRefusedError(
- errno.ECONNREFUSED,
- ('Failed varlink connection "{}"').format(address))
- except FileNotFoundError:
- raise ConnectionError(
- errno.ECONNREFUSED,
- ('Failed varlink connection "{}".'
- ' Is podman socket or service running?').format(address))
-
- def __enter__(self):
- """Return `self` upon entering the runtime context."""
- return self
-
- def __exit__(self, exc_type, exc_value, traceback):
- """Raise any exception triggered within the runtime context."""
- pass
-
- @cached_property
- def system(self):
- """Manage system model for podman."""
- return System(self._client)
-
- @cached_property
- def images(self):
- """Manage images model for libpod."""
- return Images(self._client)
-
- @cached_property
- def containers(self):
- """Manage containers model for libpod."""
- return Containers(self._client)
-
- @cached_property
- def pods(self):
- """Manage pods model for libpod."""
- return Pods(self._client)
diff --git a/contrib/python/podman/podman/libs/__init__.py b/contrib/python/podman/podman/libs/__init__.py
deleted file mode 100644
index 5193313ed..000000000
--- a/contrib/python/podman/podman/libs/__init__.py
+++ /dev/null
@@ -1,75 +0,0 @@
-"""Support files for podman API implementation."""
-import collections
-import datetime
-import functools
-
-from dateutil.parser import parse as dateutil_parse
-
-__all__ = [
- 'cached_property',
- 'datetime_format',
- 'datetime_parse',
- 'fold_keys',
-]
-
-
-def cached_property(fn):
- """Decorate property to cache return value."""
- return property(functools.lru_cache(maxsize=8)(fn))
-
-
-class ConfigDict(collections.UserDict):
- """Silently ignore None values, only take key once."""
-
- def __init__(self, **kwargs):
- """Construct dictionary."""
- super().__init__(kwargs)
-
- def __setitem__(self, key, value):
- """Store unique, not None values."""
- if value is None:
- return
-
- if super().__contains__(key):
- return
-
- super().__setitem__(key, value)
-
-
-class FoldedString(collections.UserString):
- """Foldcase sequences value."""
-
- def __init__(self, seq):
- super().__init__(seq)
- self.data.casefold()
-
-
-def fold_keys(): # noqa: D202
- """Fold case of dictionary keys."""
-
- @functools.wraps(fold_keys)
- def wrapped(mapping):
- """Fold case of dictionary keys."""
- return {k.casefold(): v for (k, v) in mapping.items()}
-
- return wrapped
-
-
-def datetime_parse(string):
- """Convert timestamps to datetime.
-
- tzinfo aware, if provided.
- """
- return dateutil_parse(string.upper(), fuzzy=True)
-
-
-def datetime_format(dt):
- """Format datetime in consistent style."""
- if isinstance(dt, str):
- return datetime_parse(dt).isoformat()
-
- if isinstance(dt, datetime.datetime):
- return dt.isoformat()
-
- raise ValueError('Unable to format {}. Type {} not supported.'.format(
- dt, type(dt)))
diff --git a/contrib/python/podman/podman/libs/_containers_attach.py b/contrib/python/podman/podman/libs/_containers_attach.py
deleted file mode 100644
index 94247d349..000000000
--- a/contrib/python/podman/podman/libs/_containers_attach.py
+++ /dev/null
@@ -1,79 +0,0 @@
-"""Exported method Container.attach()."""
-
-import collections
-import fcntl
-import logging
-import struct
-import sys
-import termios
-
-
-class Mixin:
- """Publish attach() for inclusion in Container class."""
-
- def attach(self, eot=4, stdin=None, stdout=None):
- """Attach to container's PID1 stdin and stdout.
-
- stderr is ignored.
- PseudoTTY work is done in start().
- """
- if stdin is None:
- stdin = sys.stdin.fileno()
- elif hasattr(stdin, 'fileno'):
- stdin = stdin.fileno()
-
- if stdout is None:
- stdout = sys.stdout.fileno()
- elif hasattr(stdout, 'fileno'):
- stdout = stdout.fileno()
-
- with self._client() as podman:
- attach = podman.GetAttachSockets(self._id)
-
- # This is the UDS where all the IO goes
- io_socket = attach['sockets']['io_socket']
- assert len(io_socket) <= 107,\
- 'Path length for sockets too long. {} > 107'.format(
- len(io_socket)
- )
-
- # This is the control socket where resizing events are sent to conmon
- # attach['sockets']['control_socket']
- self.pseudo_tty = collections.namedtuple(
- 'PseudoTTY',
- ['stdin', 'stdout', 'io_socket', 'control_socket', 'eot'])(
- stdin,
- stdout,
- attach['sockets']['io_socket'],
- attach['sockets']['control_socket'],
- eot,
- )
-
- @property
- def resize_handler(self):
- """Send the new window size to conmon."""
-
- def wrapped(signum, frame): # pylint: disable=unused-argument
- packed = fcntl.ioctl(self.pseudo_tty.stdout, termios.TIOCGWINSZ,
- struct.pack('HHHH', 0, 0, 0, 0))
- rows, cols, _, _ = struct.unpack('HHHH', packed)
- logging.debug('Resize window(%dx%d) using %s', rows, cols,
- self.pseudo_tty.control_socket)
-
- # TODO: Need some kind of timeout in case pipe is blocked
- with open(self.pseudo_tty.control_socket, 'w') as skt:
- # send conmon window resize message
- skt.write('1 {} {}\n'.format(rows, cols))
-
- return wrapped
-
- @property
- def log_handler(self):
- """Send command to reopen log to conmon."""
-
- def wrapped(signum, frame): # pylint: disable=unused-argument
- with open(self.pseudo_tty.control_socket, 'w') as skt:
- # send conmon reopen log message
- skt.write('2\n')
-
- return wrapped
diff --git a/contrib/python/podman/podman/libs/_containers_start.py b/contrib/python/podman/podman/libs/_containers_start.py
deleted file mode 100644
index 20130f5d6..000000000
--- a/contrib/python/podman/podman/libs/_containers_start.py
+++ /dev/null
@@ -1,82 +0,0 @@
-"""Exported method Container.start()."""
-import logging
-import os
-import select
-import signal
-import socket
-import sys
-import termios
-import tty
-
-CONMON_BUFSZ = 8192
-
-
-class Mixin:
- """Publish start() for inclusion in Container class."""
-
- def start(self):
- """Start container, return container on success.
-
- Will block if container has been detached.
- """
- with self._client() as podman:
- logging.debug('Starting Container "%s"', self._id)
- results = podman.StartContainer(self._id)
- logging.debug('Started Container "%s"', results['container'])
-
- if not hasattr(self, 'pseudo_tty') or self.pseudo_tty is None:
- return self._refresh(podman)
-
- logging.debug('Setting up PseudoTTY for Container "%s"',
- results['container'])
-
- try:
- # save off the old settings for terminal
- tcoldattr = termios.tcgetattr(self.pseudo_tty.stdin)
- tty.setraw(self.pseudo_tty.stdin)
-
- # initialize container's window size
- self.resize_handler(None, sys._getframe(0))
-
- # catch any resizing events and send the resize info
- # to the control fifo "socket"
- signal.signal(signal.SIGWINCH, self.resize_handler)
-
- except termios.error:
- tcoldattr = None
-
- try:
- # TODO: Is socket.SOCK_SEQPACKET supported in Windows?
- with socket.socket(socket.AF_UNIX,
- socket.SOCK_SEQPACKET) as skt:
- # Prepare socket for use with conmon/container
- skt.connect(self.pseudo_tty.io_socket)
-
- sources = [skt, self.pseudo_tty.stdin]
- while sources:
- logging.debug('Waiting on sources: %s', sources)
- readable, _, _ = select.select(sources, [], [])
-
- if skt in readable:
- data = skt.recv(CONMON_BUFSZ)
- if data:
- # Remove source marker when writing
- os.write(self.pseudo_tty.stdout, data[1:])
- else:
- sources.remove(skt)
-
- if self.pseudo_tty.stdin in readable:
- data = os.read(self.pseudo_tty.stdin, CONMON_BUFSZ)
- if data:
- skt.sendall(data)
-
- if self.pseudo_tty.eot in data:
- sources.clear()
- else:
- sources.remove(self.pseudo_tty.stdin)
- finally:
- if tcoldattr:
- termios.tcsetattr(self.pseudo_tty.stdin, termios.TCSADRAIN,
- tcoldattr)
- signal.signal(signal.SIGWINCH, signal.SIG_DFL)
- return self._refresh(podman)
diff --git a/contrib/python/podman/podman/libs/containers.py b/contrib/python/podman/podman/libs/containers.py
deleted file mode 100644
index 7adecea8f..000000000
--- a/contrib/python/podman/podman/libs/containers.py
+++ /dev/null
@@ -1,248 +0,0 @@
-"""Models for manipulating containers and storage."""
-import collections
-import getpass
-import json
-import logging
-import signal
-import time
-
-from . import fold_keys
-from ._containers_attach import Mixin as AttachMixin
-from ._containers_start import Mixin as StartMixin
-
-
-class Container(AttachMixin, StartMixin, collections.UserDict):
- """Model for a container."""
-
- def __init__(self, client, ident, data, refresh=True):
- """Construct Container Model."""
- super(Container, self).__init__(data)
- self._client = client
- self._id = ident
-
- if refresh:
- with client() as podman:
- self._refresh(podman)
- else:
- for k, v in self.data.items():
- setattr(self, k, v)
- if 'containerrunning' in self.data:
- setattr(self, 'running', self.data['containerrunning'])
- self.data['running'] = self.data['containerrunning']
-
- assert self._id == data['id'],\
- 'Requested container id({}) does not match store id({})'.format(
- self._id, data['id']
- )
-
- def _refresh(self, podman, tries=1):
- try:
- ctnr = podman.GetContainer(self._id)
- except BrokenPipeError:
- logging.debug('Failed GetContainer(%s) try %d/3', self._id, tries)
- if tries > 3:
- raise
- else:
- with self._client() as pman:
- self._refresh(pman, tries + 1)
- else:
- super().update(ctnr['container'])
-
- for k, v in self.data.items():
- setattr(self, k, v)
- if 'containerrunning' in self.data:
- setattr(self, 'running', self.data['containerrunning'])
- self.data['running'] = self.data['containerrunning']
-
- return self
-
- def refresh(self):
- """Refresh status fields for this container."""
- with self._client() as podman:
- return self._refresh(podman)
-
- def processes(self):
- """Show processes running in container."""
- with self._client() as podman:
- results = podman.ListContainerProcesses(self._id)
- yield from results['container']
-
- def changes(self):
- """Retrieve container changes."""
- with self._client() as podman:
- results = podman.ListContainerChanges(self._id)
- return results['container']
-
- def kill(self, sig=signal.SIGTERM, wait=25):
- """Send signal to container.
-
- default signal is signal.SIGTERM.
- wait n of seconds, 0 waits forever.
- """
- with self._client() as podman:
- podman.KillContainer(self._id, sig)
- timeout = time.time() + wait
- while True:
- self._refresh(podman)
- if self.status != 'running': # pylint: disable=no-member
- return self
-
- if wait and timeout < time.time():
- raise TimeoutError()
-
- time.sleep(0.5)
-
- def inspect(self):
- """Retrieve details about containers."""
- with self._client() as podman:
- results = podman.InspectContainer(self._id)
- obj = json.loads(results['container'], object_hook=fold_keys())
- return collections.namedtuple('ContainerInspect', obj.keys())(**obj)
-
- def export(self, target):
- """Export container from store to tarball.
-
- TODO: should there be a compress option, like images?
- """
- with self._client() as podman:
- results = podman.ExportContainer(self._id, target)
- return results['tarfile']
-
- def commit(self, image_name, **kwargs):
- """Create image from container.
-
- Keyword arguments:
- author -- change image's author
- message -- change image's message, docker format only.
- pause -- pause container during commit
- change -- Additional properties to change
-
- Change examples:
- CMD=/usr/bin/zsh
- ENTRYPOINT=/bin/sh date
- ENV=TEST=test_containers.TestContainers.test_commit
- EXPOSE=8888/tcp
- LABEL=unittest=test_commit
- USER=bozo:circus
- VOLUME=/data
- WORKDIR=/data/application
-
- All changes overwrite existing values.
- See inspect() to obtain current settings.
- """
- author = kwargs.get('author', None) or getpass.getuser()
- change = kwargs.get('change', None) or []
- message = kwargs.get('message', None) or ''
- pause = kwargs.get('pause', None) or True
-
- for c in change:
- if c.startswith('LABEL=') and c.count('=') < 2:
- raise ValueError(
- 'LABEL should have the format: LABEL=label=value, not {}'.
- format(c))
-
- with self._client() as podman:
- results = podman.Commit(self._id, image_name, change, author,
- message, pause)
- return results['image']
-
- def stop(self, timeout=25):
- """Stop container, return id on success."""
- with self._client() as podman:
- podman.StopContainer(self._id, timeout)
- return self._refresh(podman)
-
- def remove(self, force=False):
- """Remove container, return id on success.
-
- force=True, stop running container.
- """
- with self._client() as podman:
- results = podman.RemoveContainer(self._id, force)
- return results['container']
-
- def restart(self, timeout=25):
- """Restart container with timeout, return id on success."""
- with self._client() as podman:
- podman.RestartContainer(self._id, timeout)
- return self._refresh(podman)
-
- def rename(self, target): # pylint: disable=unused-argument
- """Rename container, return id on success."""
- with self._client() as podman:
- # TODO: Need arguments
- results = podman.RenameContainer()
- # TODO: fixup objects cached information
- return results['container']
-
- def resize_tty(self, width, height): # pylint: disable=unused-argument
- """Resize container tty."""
- with self._client() as podman:
- # TODO: magic re: attach(), arguments
- podman.ResizeContainerTty()
-
- def pause(self):
- """Pause container, return id on success."""
- with self._client() as podman:
- podman.PauseContainer(self._id)
- return self._refresh(podman)
-
- def unpause(self):
- """Unpause container, return id on success."""
- with self._client() as podman:
- podman.UnpauseContainer(self._id)
- return self._refresh(podman)
-
- def update_container(self, *args, **kwargs): \
- # pylint: disable=unused-argument
- """TODO: Update container..., return id on success."""
- with self._client() as podman:
- podman.UpdateContainer()
- return self._refresh(podman)
-
- def wait(self):
- """Wait for container to finish, return 'returncode'."""
- with self._client() as podman:
- results = podman.WaitContainer(self._id)
- return int(results['exitcode'])
-
- def stats(self):
- """Retrieve resource stats from the container."""
- with self._client() as podman:
- results = podman.GetContainerStats(self._id)
- obj = results['container']
- return collections.namedtuple('StatDetail', obj.keys())(**obj)
-
- def logs(self, *args, **kwargs): # pylint: disable=unused-argument
- """Retrieve container logs."""
- with self._client() as podman:
- results = podman.GetContainerLogs(self._id)
- yield from results['container']
-
-
-class Containers():
- """Model for Containers collection."""
-
- def __init__(self, client):
- """Construct model for Containers collection."""
- self._client = client
-
- def list(self):
- """List of containers in the container store."""
- with self._client() as podman:
- results = podman.ListContainers()
- for cntr in results['containers']:
- yield Container(self._client, cntr['id'], cntr, refresh=False)
-
- def delete_stopped(self):
- """Delete all stopped containers."""
- with self._client() as podman:
- results = podman.DeleteStoppedContainers()
- return results['containers']
-
- def get(self, id_):
- """Retrieve container details from store."""
- with self._client() as podman:
- cntr = podman.GetContainer(id_)
- return Container(self._client, cntr['container']['id'],
- cntr['container'])
diff --git a/contrib/python/podman/podman/libs/errors.py b/contrib/python/podman/podman/libs/errors.py
deleted file mode 100644
index 2821d3597..000000000
--- a/contrib/python/podman/podman/libs/errors.py
+++ /dev/null
@@ -1,77 +0,0 @@
-"""Error classes and wrappers for VarlinkError."""
-from varlink import VarlinkError
-
-
-class VarlinkErrorProxy(VarlinkError):
- """Class to Proxy VarlinkError methods."""
-
- def __init__(self, message, namespaced=False):
- """Construct proxy from Exception."""
- super().__init__(message.as_dict(), namespaced)
- self._message = message
- self.__module__ = 'libpod'
-
- def __getattr__(self, method):
- """Return attribute from proxied Exception."""
- if hasattr(self._message, method):
- return getattr(self._message, method)
-
- try:
- return self._message.parameters()[method]
- except KeyError:
- raise AttributeError('No such attribute: {}'.format(method))
-
-
-class ContainerNotFound(VarlinkErrorProxy):
- """Raised when Client cannot find requested container."""
-
-
-class ImageNotFound(VarlinkErrorProxy):
- """Raised when Client cannot find requested image."""
-
-
-class PodNotFound(VarlinkErrorProxy):
- """Raised when Client cannot find requested image."""
-
-
-class PodContainerError(VarlinkErrorProxy):
- """Raised when a container fails requested pod operation."""
-
-
-class NoContainerRunning(VarlinkErrorProxy):
- """Raised when no container is running in pod."""
-
-
-class NoContainersInPod(VarlinkErrorProxy):
- """Raised when Client fails to connect to runtime."""
-
-
-class ErrorOccurred(VarlinkErrorProxy):
- """Raised when an error occurs during the execution.
-
- See error() to see actual error text.
- """
-
-
-class PodmanError(VarlinkErrorProxy):
- """Raised when Client fails to connect to runtime."""
-
-
-ERROR_MAP = {
- 'io.podman.ContainerNotFound': ContainerNotFound,
- 'io.podman.ErrorOccurred': ErrorOccurred,
- 'io.podman.ImageNotFound': ImageNotFound,
- 'io.podman.NoContainerRunning': NoContainerRunning,
- 'io.podman.NoContainersInPod': NoContainersInPod,
- 'io.podman.PodContainerError': PodContainerError,
- 'io.podman.PodNotFound': PodNotFound,
- 'io.podman.RuntimeError': PodmanError,
-}
-
-
-def error_factory(exception):
- """Map Exceptions to a discrete type."""
- try:
- return ERROR_MAP[exception.error()](exception)
- except KeyError:
- return exception
diff --git a/contrib/python/podman/podman/libs/images.py b/contrib/python/podman/podman/libs/images.py
deleted file mode 100644
index 29ebe2c0f..000000000
--- a/contrib/python/podman/podman/libs/images.py
+++ /dev/null
@@ -1,164 +0,0 @@
-"""Models for manipulating images in/to/from storage."""
-import collections
-import copy
-import json
-import logging
-
-from . import ConfigDict, fold_keys
-from .containers import Container
-
-
-class Image(collections.UserDict):
- """Model for an Image."""
-
- def __init__(self, client, id, data):
- """Construct Image Model."""
- super().__init__(data)
- for k, v in data.items():
- setattr(self, k, v)
-
- self._id = id
- self._client = client
-
- assert self._id == data['id'],\
- 'Requested image id({}) does not match store id({})'.format(
- self._id, data['id']
- )
-
- @staticmethod
- def _split_token(values=None, sep='='):
- if not values:
- return {}
- return {
- k: v1 for k, v1 in (v0.split(sep, 1) for v0 in values)
- }
-
- def create(self, *args, **kwargs):
- """Create container from image.
-
- Pulls defaults from image.inspect()
- """
- details = self.inspect()
-
- config = ConfigDict(image_id=self._id, **kwargs)
- config['command'] = details.config.get('cmd')
- config['env'] = self._split_token(details.config.get('env'))
- config['image'] = copy.deepcopy(details.repotags[0])
- config['labels'] = copy.deepcopy(details.labels)
- config['net_mode'] = 'bridge'
- config['network'] = 'bridge'
-
- logging.debug('Image %s: create config: %s', self._id, config)
- with self._client() as podman:
- id_ = podman.CreateContainer(config)['container']
- cntr = podman.GetContainer(id_)
- return Container(self._client, id_, cntr['container'])
-
- container = create
-
- def export(self, dest, compressed=False):
- """Write image to dest, return id on success."""
- with self._client() as podman:
- results = podman.ExportImage(self._id, dest, compressed)
- return results['image']
-
- def history(self):
- """Retrieve image history."""
- with self._client() as podman:
- for r in podman.HistoryImage(self._id)['history']:
- yield collections.namedtuple('HistoryDetail', r.keys())(**r)
-
- def inspect(self):
- """Retrieve details about image."""
- with self._client() as podman:
- results = podman.InspectImage(self._id)
- obj = json.loads(results['image'], object_hook=fold_keys())
- return collections.namedtuple('ImageInspect', obj.keys())(**obj)
-
- def push(self, target, tlsverify=True):
- """Copy image to target, return id on success."""
- with self._client() as podman:
- results = podman.PushImage(self._id, target, tlsverify)
- return results['image']
-
- def remove(self, force=False):
- """Delete image, return id on success.
-
- force=True, stop any running containers using image.
- """
- with self._client() as podman:
- results = podman.RemoveImage(self._id, force)
- return results['image']
-
- def tag(self, tag):
- """Tag image."""
- with self._client() as podman:
- results = podman.TagImage(self._id, tag)
- return results['image']
-
-
-class Images():
- """Model for Images collection."""
-
- def __init__(self, client):
- """Construct model for Images collection."""
- self._client = client
-
- def list(self):
- """List all images in the libpod image store."""
- with self._client() as podman:
- results = podman.ListImages()
- for img in results['images']:
- yield Image(self._client, img['id'], img)
-
- def build(self, dockerfile=None, tags=None, **kwargs):
- """Build container from image.
-
- See podman-build.1.md for kwargs details.
- """
- if dockerfile is None:
- raise ValueError('"dockerfile" is a required argument.')
- elif not hasattr(dockerfile, '__iter__'):
- raise ValueError('"dockerfile" is required to be an iter.')
-
- if tags is None:
- raise ValueError('"tags" is a required argument.')
- elif not hasattr(tags, '__iter__'):
- raise ValueError('"tags" is required to be an iter.')
-
- config = ConfigDict(dockerfile=dockerfile, tags=tags, **kwargs)
- with self._client() as podman:
- result = podman.BuildImage(config)
- return self.get(result['image']['id']), \
- (line for line in result['image']['logs'])
-
- def delete_unused(self):
- """Delete Images not associated with a container."""
- with self._client() as podman:
- results = podman.DeleteUnusedImages()
- return results['images']
-
- def import_image(self, source, reference, message='', changes=None):
- """Read image tarball from source and save in image store."""
- with self._client() as podman:
- results = podman.ImportImage(source, reference, message, changes)
- return results['image']
-
- def pull(self, source):
- """Copy image from registry to image store."""
- with self._client() as podman:
- results = podman.PullImage(source)
- return results['id']
-
- def search(self, id_, limit=25):
- """Search registries for id."""
- with self._client() as podman:
- results = podman.SearchImage(id_, limit)
- for img in results['images']:
- yield collections.namedtuple('ImageSearch', img.keys())(**img)
-
- def get(self, id_):
- """Get Image from id."""
- with self._client() as podman:
- result = podman.GetImage(id_)
- return Image(self._client, result['image']['id'], result['image'])
diff --git a/contrib/python/podman/podman/libs/pods.py b/contrib/python/podman/podman/libs/pods.py
deleted file mode 100644
index 2a85f2624..000000000
--- a/contrib/python/podman/podman/libs/pods.py
+++ /dev/null
@@ -1,163 +0,0 @@
-"""Model for accessing details of Pods from podman service."""
-import collections
-import json
-import signal
-import time
-
-from . import ConfigDict, FoldedString, fold_keys
-
-
-class Pod(collections.UserDict):
- """Model for a Pod."""
-
- def __init__(self, client, ident, data):
- """Construct Pod model."""
- super().__init__(data)
-
- self._ident = ident
- self._client = client
-
- with client() as podman:
- self._refresh(podman)
-
- def _refresh(self, podman):
- pod = podman.GetPod(self._ident)
- super().update(pod['pod'])
-
- for k, v in self.data.items():
- setattr(self, k, v)
- return self
-
- def inspect(self):
- """Retrieve details about pod."""
- with self._client() as podman:
- results = podman.InspectPod(self._ident)
- obj = json.loads(results['pod'], object_hook=fold_keys())
- obj['id'] = obj['config']['id']
- return collections.namedtuple('PodInspect', obj.keys())(**obj)
-
- def kill(self, signal_=signal.SIGTERM, wait=25):
- """Send signal to all containers in pod.
-
- default signal is signal.SIGTERM.
- wait n of seconds, 0 waits forever.
- """
- with self._client() as podman:
- podman.KillPod(self._ident, signal_)
- timeout = time.time() + wait
- while True:
- # pylint: disable=maybe-no-member
- self._refresh(podman)
- running = FoldedString(self.status)
- if running != 'running':
- break
-
- if wait and timeout < time.time():
- raise TimeoutError()
-
- time.sleep(0.5)
- return self
-
- def pause(self):
- """Pause all containers in the pod."""
- with self._client() as podman:
- podman.PausePod(self._ident)
- return self._refresh(podman)
-
- def refresh(self):
- """Refresh status fields for this pod."""
- with self._client() as podman:
- return self._refresh(podman)
-
- def remove(self, force=False):
- """Remove pod and its containers returning pod ident.
-
- force=True, stop any running container.
- """
- with self._client() as podman:
- results = podman.RemovePod(self._ident, force)
- return results['pod']
-
- def restart(self):
- """Restart all containers in the pod."""
- with self._client() as podman:
- podman.RestartPod(self._ident)
- return self._refresh(podman)
-
- def stats(self):
- """Stats on all containers in the pod."""
- with self._client() as podman:
- results = podman.GetPodStats(self._ident)
- for obj in results['containers']:
- yield collections.namedtuple('ContainerStats', obj.keys())(**obj)
-
- def start(self):
- """Start all containers in the pod."""
- with self._client() as podman:
- podman.StartPod(self._ident)
- return self._refresh(podman)
-
- def stop(self):
- """Stop all containers in the pod."""
- with self._client() as podman:
- podman.StopPod(self._ident)
- return self._refresh(podman)
-
- def top(self):
- """Display stats for all containers."""
- with self._client() as podman:
- results = podman.TopPod(self._ident)
- return results['pod']
-
- def unpause(self):
- """Unpause all containers in the pod."""
- with self._client() as podman:
- podman.UnpausePod(self._ident)
- return self._refresh(podman)
-
- def wait(self):
- """Wait for all containers to exit."""
- with self._client() as podman:
- results = podman.WaitPod(self._ident)
- return results['pod']
-
-
-class Pods():
- """Model for accessing pods."""
-
- def __init__(self, client):
- """Construct pod model."""
- self._client = client
-
- def create(self,
- ident=None,
- cgroupparent=None,
- labels=None,
- share=None,
- infra=False):
- """Create a new empty pod."""
- config = ConfigDict(
- name=ident,
- cgroupParent=cgroupparent,
- labels=labels,
- share=share,
- infra=infra,
- )
-
- with self._client() as podman:
- result = podman.CreatePod(config)
- details = podman.GetPod(result['pod'])
- return Pod(self._client, result['pod'], details['pod'])
-
- def get(self, ident):
- """Get Pod from ident."""
- with self._client() as podman:
- result = podman.GetPod(ident)
- return Pod(self._client, result['pod']['id'], result['pod'])
-
- def list(self):
- """List all pods."""
- with self._client() as podman:
- results = podman.ListPods()
- for pod in results['pods']:
- yield Pod(self._client, pod['id'], pod)
diff --git a/contrib/python/podman/podman/libs/system.py b/contrib/python/podman/podman/libs/system.py
deleted file mode 100644
index c611341e4..000000000
--- a/contrib/python/podman/podman/libs/system.py
+++ /dev/null
@@ -1,40 +0,0 @@
-"""Models for accessing details from varlink server."""
-import collections
-
-import pkg_resources
-
-from . import cached_property
-
-
-class System():
- """Model for accessing system resources."""
-
- def __init__(self, client):
- """Construct system model."""
- self._client = client
-
- @cached_property
- def versions(self):
- """Access versions."""
- with self._client() as podman:
- vers = podman.GetVersion()['version']
-
- client = '0.0.0'
- try:
- client = pkg_resources.get_distribution('podman').version
- except Exception: # pylint: disable=broad-except
- pass
- vers['client_version'] = client
- return collections.namedtuple('Version', vers.keys())(**vers)
-
- def info(self):
- """Return podman info."""
- with self._client() as podman:
- info = podman.GetInfo()['info']
- return collections.namedtuple('Info', info.keys())(**info)
-
- def ping(self):
- """Return True if server awake."""
- with self._client() as podman:
- response = podman.Ping()
- return response['ping']['message'] == 'OK'
diff --git a/contrib/python/podman/podman/libs/tunnel.py b/contrib/python/podman/podman/libs/tunnel.py
deleted file mode 100644
index ac1dff594..000000000
--- a/contrib/python/podman/podman/libs/tunnel.py
+++ /dev/null
@@ -1,190 +0,0 @@
-"""Cache for SSH tunnels."""
-import collections
-import getpass
-import logging
-import os
-import subprocess
-import threading
-import time
-import weakref
-from contextlib import suppress
-
-import psutil
-
-Context = collections.namedtuple('Context', (
- 'uri',
- 'interface',
- 'local_socket',
- 'remote_socket',
- 'username',
- 'hostname',
- 'port',
- 'identity_file',
-))
-Context.__new__.__defaults__ = (None, ) * len(Context._fields)
-
-
-class Portal(collections.MutableMapping):
- """Expiring container for tunnels."""
-
- def __init__(self, sweap=25):
- """Construct portal, reap tunnels every sweap seconds."""
- self.data = collections.OrderedDict()
- self.sweap = sweap
- self.ttl = sweap * 2
- self.lock = threading.RLock()
- self._schedule_reaper()
-
- def __getitem__(self, key):
- """Given uri return tunnel and update TTL."""
- with self.lock:
- value, _ = self.data[key]
- self.data[key] = (value, time.time() + self.ttl)
- self.data.move_to_end(key)
- return value
-
- def __setitem__(self, key, value):
- """Store given tunnel keyed with uri."""
- if not isinstance(value, Tunnel):
- raise ValueError('Portals only support Tunnels.')
-
- with self.lock:
- self.data[key] = (value, time.time() + self.ttl)
- self.data.move_to_end(key)
-
- def __delitem__(self, key):
- """Remove and close tunnel from portal."""
- with self.lock:
- value, _ = self.data[key]
- del self.data[key]
- value.close()
- del value
-
- def __iter__(self):
- """Iterate tunnels."""
- with self.lock:
- values = self.data.values()
-
- for tunnel, _ in values:
- yield tunnel
-
- def __len__(self):
- """Return number of tunnels in portal."""
- with self.lock:
- return len(self.data)
-
- def _schedule_reaper(self):
- timer = threading.Timer(interval=self.sweap, function=self.reap)
- timer.setName('PortalReaper')
- timer.setDaemon(True)
- timer.start()
-
- def reap(self):
- """Remove tunnels who's TTL has expired."""
- now = time.time()
- with self.lock:
- reaped_data = self.data.copy()
- for entry in reaped_data.items():
- if entry[1][1] < now:
- del self.data[entry[0]]
- else:
- # StopIteration as soon as possible
- break
- self._schedule_reaper()
-
-
-class Tunnel():
- """SSH tunnel."""
-
- def __init__(self, context):
- """Construct Tunnel."""
- self.context = context
- self._closed = True
-
- @property
- def closed(self):
- """Is tunnel closed."""
- return self._closed
-
- def bore(self):
- """Create SSH tunnel from given context."""
- cmd = ['ssh', '-fNT']
-
- if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
- cmd.append('-v')
- else:
- cmd.append('-q')
-
- if self.context.port:
- cmd.extend(('-p', str(self.context.port)))
-
- cmd.extend(('-L', '{}:{}'.format(self.context.local_socket,
- self.context.remote_socket)))
- if self.context.identity_file:
- cmd.extend(('-i', self.context.identity_file))
-
- cmd.append('{}@{}'.format(self.context.username,
- self.context.hostname))
-
- logging.debug('Opening tunnel "%s", cmd "%s"', self.context.uri,
- ' '.join(cmd))
-
- tunnel = subprocess.Popen(cmd, close_fds=True)
- # The return value of Popen() has no long term value as that process
- # has already exited by the time control is returned here. This is a
- # side effect of the -f option. wait() will be called to clean up
- # resources.
- for _ in range(300):
- # TODO: Make timeout configurable
- if os.path.exists(self.context.local_socket) \
- or tunnel.returncode is not None:
- break
- with suppress(subprocess.TimeoutExpired):
- # waiting for either socket to be created
- # or first child to exit
- tunnel.wait(0.5)
- else:
- raise TimeoutError(
- 'Failed to create tunnel "{}", using: "{}"'.format(
- self.context.uri, ' '.join(cmd)))
- if tunnel.returncode is not None and tunnel.returncode != 0:
- raise subprocess.CalledProcessError(tunnel.returncode,
- ' '.join(cmd))
- tunnel.wait()
-
- self._closed = False
- weakref.finalize(self, self.close)
- return self
-
- def close(self):
- """Close SSH tunnel."""
- logging.debug('Closing tunnel "%s"', self.context.uri)
-
- if self._closed:
- return
-
- # Find all ssh instances for user with uri tunnel the hard way...
- targets = [
- p
- for p in psutil.process_iter(attrs=['name', 'username', 'cmdline'])
- if p.info['username'] == getpass.getuser()
- and p.info['name'] == 'ssh'
- and self.context.local_socket in ' '.join(p.info['cmdline'])
- ] # yapf: disable
-
- # ask nicely for ssh to quit, reap results
- for proc in targets:
- proc.terminate()
- _, alive = psutil.wait_procs(targets, timeout=300)
-
- # kill off the uncooperative, then report any stragglers
- for proc in alive:
- proc.kill()
- _, alive = psutil.wait_procs(targets, timeout=300)
-
- for proc in alive:
- logging.info('process %d survived SIGKILL, giving up.', proc.pid)
-
- with suppress(OSError):
- os.remove(self.context.local_socket)
- self._closed = True
diff --git a/contrib/python/podman/requirements.txt b/contrib/python/podman/requirements.txt
deleted file mode 100644
index 1caf5e286..000000000
--- a/contrib/python/podman/requirements.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-psutil
-python-dateutil
-setuptools>=39
-varlink
diff --git a/contrib/python/podman/setup.py b/contrib/python/podman/setup.py
deleted file mode 100755
index 9d54bb3ac..000000000
--- a/contrib/python/podman/setup.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-
-import os
-
-from setuptools import find_packages, setup
-
-
-root = os.path.abspath(os.path.dirname(__file__))
-
-with open(os.path.join(root, 'README.md')) as me:
- readme = me.read()
-
-with open(os.path.join(root, 'requirements.txt')) as r:
- requirements = r.read().splitlines()
-
-
-setup(
- name='podman',
- version=os.environ.get('PODMAN_VERSION', '0.0.0'),
- description='A library for communicating with a Podman server',
- author='Jhon Honce',
- author_email='jhonce@redhat.com',
- license='Apache Software License',
- long_description=readme,
- include_package_data=True,
- install_requires=requirements,
- packages=find_packages(exclude=['test']),
- python_requires='>=3',
- zip_safe=True,
- url='http://github.com/containers/libpod',
- keywords='varlink libpod podman',
- classifiers=[
- 'Development Status :: 3 - Alpha',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: Apache Software License',
- 'Programming Language :: Python :: 3.4',
- 'Topic :: Software Development',
- ])
diff --git a/contrib/python/podman/test/__init__.py b/contrib/python/podman/test/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/contrib/python/podman/test/__init__.py
+++ /dev/null
diff --git a/contrib/python/podman/test/podman_testcase.py b/contrib/python/podman/test/podman_testcase.py
deleted file mode 100644
index da73c1024..000000000
--- a/contrib/python/podman/test/podman_testcase.py
+++ /dev/null
@@ -1,112 +0,0 @@
-"""Base for podman tests."""
-import contextlib
-import functools
-import itertools
-import os
-import subprocess
-import time
-import unittest
-
-from varlink import VarlinkError
-
-MethodNotImplemented = 'org.varlink.service.MethodNotImplemented'
-
-
-class PodmanTestCase(unittest.TestCase):
- """Hide the sausage making of initializing storage."""
-
- @classmethod
- def setUpClass(cls):
- """Fixture to setup podman test case."""
- if hasattr(PodmanTestCase, 'alpine_process'):
- PodmanTestCase.tearDownClass()
-
- def run_cmd(*args):
- cmd = list(itertools.chain(*args))
- try:
- pid = subprocess.Popen(
- cmd,
- close_fds=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- out, err = pid.communicate()
- except OSError as e:
- print('{}: {}({})'.format(cmd, e.strerror, e.returncode))
- except ValueError as e:
- print('{}: {}'.format(cmd, e.message))
- raise
- else:
- return out.strip()
-
- tmpdir = os.environ.get('TMPDIR', '/tmp')
- podman_args = [
- '--storage-driver=vfs',
- '--cgroup-manager=cgroupfs',
- '--root={}/crio'.format(tmpdir),
- '--runroot={}/crio-run'.format(tmpdir),
- '--cni-config-dir={}/cni/net.d'.format(tmpdir),
- ]
-
- run_podman = functools.partial(run_cmd, ['podman'], podman_args)
-
- id = run_podman(['pull', 'alpine'])
- setattr(PodmanTestCase, 'alpine_id', id)
-
- run_podman(['pull', 'busybox'])
- run_podman(['images'])
-
- run_cmd(['rm', '-f', '{}/alpine_gold.tar'.format(tmpdir)])
- run_podman([
- 'save', '--output', '{}/alpine_gold.tar'.format(tmpdir), 'alpine'
- ])
-
- PodmanTestCase.alpine_log = open(
- os.path.join('/tmp/', 'alpine.log'), 'w')
-
- cmd = ['podman']
- cmd.extend(podman_args)
- # cmd.extend(['run', '-d', 'alpine', 'sleep', '500'])
- cmd.extend(['run', '-dt', 'alpine', '/bin/sh'])
- PodmanTestCase.alpine_process = subprocess.Popen(
- cmd,
- stdout=PodmanTestCase.alpine_log,
- stderr=subprocess.STDOUT,
- )
-
- PodmanTestCase.busybox_log = open(
- os.path.join('/tmp/', 'busybox.log'), 'w')
-
- cmd = ['podman']
- cmd.extend(podman_args)
- cmd.extend(['create', 'busybox'])
- PodmanTestCase.busybox_process = subprocess.Popen(
- cmd,
- stdout=PodmanTestCase.busybox_log,
- stderr=subprocess.STDOUT,
- )
- # give podman time to start ctnr
- time.sleep(2)
-
- # Close our handle of file
- PodmanTestCase.alpine_log.close()
- PodmanTestCase.busybox_log.close()
-
- @classmethod
- def tearDownClass(cls):
- """Fixture to clean up after podman unittest."""
- try:
- PodmanTestCase.alpine_process.kill()
- assert 0 == PodmanTestCase.alpine_process.wait(500)
- delattr(PodmanTestCase, 'alpine_process')
-
- PodmanTestCase.busybox_process.kill()
- assert 0 == PodmanTestCase.busybox_process.wait(500)
- except Exception as e:
- print('Exception: {}'.format(e))
- raise
-
- @contextlib.contextmanager
- def assertRaisesNotImplemented(self):
- """Sugar for unimplemented varlink methods."""
- with self.assertRaisesRegex(VarlinkError, MethodNotImplemented):
- yield
diff --git a/contrib/python/podman/test/retry_decorator.py b/contrib/python/podman/test/retry_decorator.py
deleted file mode 100644
index 31e06f382..000000000
--- a/contrib/python/podman/test/retry_decorator.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""Decorator to retry failed method."""
-import functools
-import time
-
-
-def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, print_=None):
- """Retry calling the decorated function using an exponential backoff.
-
- Specialized for our unittests
- from:
- http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
- original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
-
- :param ExceptionToCheck: the exception to check. may be a tuple of
- exceptions to check
- :type ExceptionToCheck: Exception or tuple
- :param tries: number of times to try (not retry) before giving up
- :type tries: int
- :param delay: initial delay between retries in seconds
- :type delay: int
- :param backoff: backoff multiplier e.g. value of 2 will double the delay
- each retry
- :type backoff: int
- """
- def deco_retry(f):
- @functools.wraps(f)
- def f_retry(*args, **kwargs):
- mtries, mdelay = tries, delay
- while mtries > 1:
- try:
- return f(*args, **kwargs)
- except ExceptionToCheck as e:
- if print_:
- print_('{}, Retrying in {} seconds...'.format(
- str(e), mdelay))
- time.sleep(mdelay)
- mtries -= 1
- mdelay *= backoff
- return f(*args, **kwargs)
-
- return f_retry # true decorator
-
- return deco_retry
diff --git a/contrib/python/podman/test/test_client.py b/contrib/python/podman/test/test_client.py
deleted file mode 100644
index 3fc6d39dc..000000000
--- a/contrib/python/podman/test/test_client.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from __future__ import absolute_import
-
-import unittest
-from unittest.mock import patch
-
-import podman
-from podman.client import BaseClient, Client, LocalClient, RemoteClient
-
-
-class TestClient(unittest.TestCase):
- def setUp(self):
- pass
-
- @patch('podman.libs.system.System.ping', return_value=True)
- def test_local(self, mock_ping):
- p = Client(
- uri='unix:/run/podman',
- interface='io.podman',
- )
-
- self.assertIsInstance(p._client, LocalClient)
- self.assertIsInstance(p._client, BaseClient)
-
- mock_ping.assert_called_once_with()
-
- @patch('podman.libs.system.System.ping', return_value=True)
- def test_remote(self, mock_ping):
- p = Client(
- uri='unix:/run/podman',
- interface='io.podman',
- remote_uri='ssh://user@hostname/run/podman/podman',
- identity_file='~/.ssh/id_rsa')
-
- self.assertIsInstance(p._client, BaseClient)
- mock_ping.assert_called_once_with()
diff --git a/contrib/python/podman/test/test_containers.py b/contrib/python/podman/test/test_containers.py
deleted file mode 100644
index 5201956e8..000000000
--- a/contrib/python/podman/test/test_containers.py
+++ /dev/null
@@ -1,244 +0,0 @@
-import os
-import signal
-import unittest
-from pathlib import Path
-from test.podman_testcase import PodmanTestCase
-from test.retry_decorator import retry
-
-import podman
-
-
-class TestContainers(PodmanTestCase):
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super().tearDownClass()
-
- def setUp(self):
- self.tmpdir = os.environ['TMPDIR']
- self.host = os.environ['PODMAN_HOST']
-
- self.pclient = podman.Client(self.host)
- self.loadCache()
-
- def tearDown(self):
- pass
-
- def loadCache(self):
- self.containers = list(self.pclient.containers.list())
-
- self.alpine_ctnr = next(
- iter([c for c in self.containers if 'alpine' in c['image']] or []),
- None)
-
- if self.alpine_ctnr and self.alpine_ctnr.status != 'running':
- self.alpine_ctnr.start()
-
- def test_list(self):
- self.assertGreaterEqual(len(self.containers), 2)
- self.assertIsNotNone(self.alpine_ctnr)
- self.assertIn('alpine', self.alpine_ctnr.image)
-
- def test_delete_stopped(self):
- before = len(self.containers)
-
- self.alpine_ctnr.stop()
- target = self.alpine_ctnr.id
- actual = self.pclient.containers.delete_stopped()
- self.assertIn(target, actual)
-
- self.loadCache()
- after = len(self.containers)
-
- self.assertLess(after, before)
- TestContainers.setUpClass()
-
- def test_get(self):
- actual = self.pclient.containers.get(self.alpine_ctnr.id)
- for k in ['id', 'status', 'ports']:
- self.assertEqual(actual[k], self.alpine_ctnr[k])
-
- with self.assertRaises(podman.ContainerNotFound):
- self.pclient.containers.get("bozo")
-
- def test_attach(self):
- # StringIO does not support fileno() so we had to go old school
- input = os.path.join(self.tmpdir, 'test_attach.stdin')
- output = os.path.join(self.tmpdir, 'test_attach.stdout')
-
- with open(input, 'w+') as mock_in, open(output, 'w+') as mock_out:
- # double quote is indeed in the expected place
- mock_in.write('echo H"ello, World"; exit\n')
- mock_in.seek(0, 0)
-
- ctnr = self.pclient.images.get(self.alpine_ctnr.image).container(
- detach=True, tty=True)
- ctnr.attach(stdin=mock_in.fileno(), stdout=mock_out.fileno())
- ctnr.start()
-
- mock_out.flush()
- mock_out.seek(0, 0)
- output = mock_out.read()
- self.assertIn('Hello', output)
-
- ctnr.remove(force=True)
-
- def test_processes(self):
- actual = list(self.alpine_ctnr.processes())
- self.assertGreaterEqual(len(actual), 2)
-
- def test_start_stop_wait(self):
- ctnr = self.alpine_ctnr.stop()
- self.assertFalse(ctnr['running'])
-
- ctnr.start()
- self.assertTrue(ctnr.running)
-
- ctnr.stop()
- self.assertFalse(ctnr['containerrunning'])
-
- actual = ctnr.wait()
- self.assertGreaterEqual(actual, 0)
-
- def test_changes(self):
- actual = self.alpine_ctnr.changes()
-
- self.assertListEqual(
- sorted(['changed', 'added', 'deleted']), sorted(
- list(actual.keys())))
-
- # TODO: brittle, depends on knowing history of ctnr
- self.assertGreaterEqual(len(actual['changed']), 0)
- self.assertGreaterEqual(len(actual['added']), 0)
- self.assertEqual(len(actual['deleted']), 0)
-
- def test_kill(self):
- self.assertTrue(self.alpine_ctnr.running)
- ctnr = self.alpine_ctnr.kill(signal.SIGKILL)
- self.assertFalse(ctnr.running)
-
- def test_inspect(self):
- actual = self.alpine_ctnr.inspect()
- self.assertEqual(actual.id, self.alpine_ctnr.id)
- # TODO: Datetime values from inspect missing offset in CI instance
- # self.assertEqual(
- # datetime_parse(actual.created),
- # datetime_parse(self.alpine_ctnr.createdat))
-
- def test_export(self):
- target = os.path.join(self.tmpdir, 'alpine_export_ctnr.tar')
-
- actual = self.alpine_ctnr.export(target)
- self.assertEqual(actual, target)
- self.assertTrue(os.path.isfile(target))
- self.assertGreater(os.path.getsize(target), 0)
-
- def test_commit(self):
- # TODO: Test for STOPSIGNAL when supported by OCI
- # TODO: Test for message when supported by OCI
- details = self.pclient.images.get(self.alpine_ctnr.image).inspect()
- changes = ['ENV=' + i for i in details.config['env']]
- changes.append('CMD=/usr/bin/zsh')
- changes.append('ENTRYPOINT=/bin/sh date')
- changes.append('ENV=TEST=test_containers.TestContainers.test_commit')
- changes.append('EXPOSE=80')
- changes.append('EXPOSE=8888')
- changes.append('LABEL=unittest=test_commit')
- changes.append('USER=bozo:circus')
- changes.append('VOLUME=/data')
- changes.append('WORKDIR=/data/application')
-
- id = self.alpine_ctnr.commit(
- 'alpine3', author='Bozo the clown', change=changes, pause=True)
- img = self.pclient.images.get(id)
- self.assertIsNotNone(img)
-
- details = img.inspect()
- self.assertEqual(details.author, 'Bozo the clown')
- self.assertListEqual(['/usr/bin/zsh'], details.config['cmd'])
- self.assertListEqual(['/bin/sh date'],
- details.config['entrypoint'])
- self.assertIn('TEST=test_containers.TestContainers.test_commit',
- details.config['env'])
- self.assertTrue(
- [e for e in details.config['env'] if 'PATH=' in e])
- self.assertDictEqual({
- '80': {},
- '8888': {},
- }, details.config['exposedports'])
- self.assertDictEqual({'unittest': 'test_commit'}, details.labels)
- self.assertEqual('bozo:circus', details.config['user'])
- self.assertEqual({'/data': {}}, details.config['volumes'])
- self.assertEqual('/data/application',
- details.config['workingdir'])
-
- def test_remove(self):
- before = len(self.containers)
-
- with self.assertRaises(podman.ErrorOccurred):
- self.alpine_ctnr.remove()
-
- self.assertEqual(
- self.alpine_ctnr.id, self.alpine_ctnr.remove(force=True))
- self.loadCache()
- after = len(self.containers)
-
- self.assertLess(after, before)
- TestContainers.setUpClass()
-
- def test_restart(self):
- self.assertTrue(self.alpine_ctnr.running)
- before = self.alpine_ctnr.runningfor
-
- ctnr = self.alpine_ctnr.restart()
- self.assertTrue(ctnr.running)
-
- after = self.alpine_ctnr.runningfor
-
- # TODO: restore check when restart zeros counter
- # self.assertLess(after, before)
-
- def test_rename(self):
- with self.assertRaisesNotImplemented():
- self.alpine_ctnr.rename('new_alpine')
-
- def test_resize_tty(self):
- with self.assertRaisesNotImplemented():
- self.alpine_ctnr.resize_tty(132, 43)
-
- def test_pause_unpause(self):
- self.assertTrue(self.alpine_ctnr.running)
-
- ctnr = self.alpine_ctnr.pause()
- self.assertEqual(ctnr.status, 'paused')
-
- ctnr = self.alpine_ctnr.unpause()
- self.assertTrue(ctnr.running)
- self.assertTrue(ctnr.status, 'running')
-
- # creating cgoups can be flakey
- @retry(podman.libs.errors.ErrorOccurred, tries=4, delay=2, print_=print)
- def test_stats(self):
- try:
- self.assertTrue(self.alpine_ctnr.running)
-
- actual = self.alpine_ctnr.stats()
- self.assertEqual(self.alpine_ctnr.id, actual.id)
- self.assertEqual(self.alpine_ctnr.names, actual.name)
- except Exception:
- info = Path('/proc/self/mountinfo')
- with info.open() as fd:
- print('{} {}'.format(self.alpine_ctnr.id, info))
- print(fd.read())
-
- def test_logs(self):
- self.assertTrue(self.alpine_ctnr.running)
- actual = list(self.alpine_ctnr.logs())
- self.assertIsNotNone(actual)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/contrib/python/podman/test/test_images.py b/contrib/python/podman/test/test_images.py
deleted file mode 100644
index af6d4741e..000000000
--- a/contrib/python/podman/test/test_images.py
+++ /dev/null
@@ -1,174 +0,0 @@
-import itertools
-import os
-import unittest
-from collections import Counter
-from datetime import datetime, timezone
-from test.podman_testcase import PodmanTestCase
-
-import podman
-from podman import FoldedString
-
-
-class TestImages(PodmanTestCase):
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super().tearDownClass()
-
- def setUp(self):
- self.tmpdir = os.environ['TMPDIR']
- self.host = os.environ['PODMAN_HOST']
-
- self.pclient = podman.Client(self.host)
- self.images = self.loadCache()
-
- def tearDown(self):
- pass
-
- def loadCache(self):
- with podman.Client(self.host) as pclient:
- self.images = list(pclient.images.list())
-
- self.alpine_image = next(
- iter([
- i for i in self.images
- if 'docker.io/library/alpine:latest' in i['repoTags']
- ] or []), None)
-
- return self.images
-
- def test_list(self):
- actual = self.loadCache()
- self.assertGreaterEqual(len(actual), 2)
- self.assertIsNotNone(self.alpine_image)
-
- @unittest.skip('TODO: missing buildah json file')
- def test_build(self):
- path = os.path.join(self.tmpdir, 'ctnr', 'Dockerfile')
- img, logs = self.pclient.images.build(
- dockerfile=[path],
- tags=['alpine-unittest'],
- )
- self.assertIsNotNone(img)
- self.assertIn('localhost/alpine-unittest:latest', img.repoTags)
- self.assertLess(
- podman.datetime_parse(img.created), datetime.now(timezone.utc))
- self.assertTrue(logs)
-
- def test_create(self):
- img_details = self.alpine_image.inspect()
-
- actual = self.alpine_image.container(command=['sleep', '1h'])
- self.assertIsNotNone(actual)
- self.assertEqual(FoldedString(actual.status), 'configured')
-
- ctnr = actual.start()
- self.assertEqual(FoldedString(ctnr.status), 'running')
-
- ctnr_details = ctnr.inspect()
- for e in img_details.config['env']:
- self.assertIn(e, ctnr_details.config['env'])
-
- def test_export(self):
- path = os.path.join(self.tmpdir, 'alpine_export.tar')
- target = 'oci-archive:{}:latest'.format(path)
-
- actual = self.alpine_image.export(target, False)
- self.assertTrue(actual)
- self.assertTrue(os.path.isfile(path))
-
- def test_get(self):
- actual = self.pclient.images.get(self.alpine_image.id)
- self.assertEqual(actual, self.alpine_image)
-
- def test_history(self):
- records = []
- bucket = Counter()
- for record in self.alpine_image.history():
- self.assertIn(record.id, (self.alpine_image.id, '<missing>'))
- bucket[record.id] += 1
- records.append(record)
-
- self.assertGreater(bucket[self.alpine_image.id], 0)
- self.assertEqual(sum(bucket.values()), len(records))
-
- def test_inspect(self):
- actual = self.alpine_image.inspect()
- self.assertEqual(actual.id, self.alpine_image.id)
-
- def test_push(self):
- path = '{}/alpine_push'.format(self.tmpdir)
- target = 'dir:{}'.format(path)
- self.alpine_image.push(target, tlsverify=False)
-
- self.assertTrue(os.path.isfile(os.path.join(path, 'manifest.json')))
- self.assertTrue(os.path.isfile(os.path.join(path, 'version')))
-
- def test_tag(self):
- self.assertEqual(self.alpine_image.id,
- self.alpine_image.tag('alpine:fubar'))
- self.loadCache()
- self.assertIn('localhost/alpine:fubar', self.alpine_image.repoTags)
-
- def test_remove(self):
- before = self.loadCache()
-
- # assertRaises doesn't follow the import name :(
- with self.assertRaises(podman.ErrorOccurred):
- self.alpine_image.remove()
-
- actual = self.alpine_image.remove(force=True)
- self.assertEqual(self.alpine_image.id, actual)
- after = self.loadCache()
-
- self.assertLess(len(after), len(before))
- TestImages.setUpClass()
- self.loadCache()
-
- def test_import_delete_unused(self):
- before = self.loadCache()
- # create unused image, so we have something to delete
- source = os.path.join(self.tmpdir, 'alpine_gold.tar')
- new_img = self.pclient.images.import_image(
- source,
- 'alpine2:latest',
- 'unittest.test_import',
- )
- after = self.loadCache()
-
- self.assertEqual(len(before) + 1, len(after))
- self.assertIsNotNone(
- next(iter([i for i in after if new_img in i['id']] or []), None))
-
- actual = self.pclient.images.delete_unused()
- self.assertIn(new_img, actual)
-
- after = self.loadCache()
- self.assertGreaterEqual(len(before), len(after))
-
- TestImages.setUpClass()
- self.loadCache()
-
- def test_pull(self):
- before = self.loadCache()
- actual = self.pclient.images.pull('prom/busybox:latest')
- after = self.loadCache()
-
- self.assertEqual(len(before) + 1, len(after))
- self.assertIsNotNone(
- next(iter([i for i in after if actual in i['id']] or []), None))
-
- def test_search(self):
- actual = self.pclient.images.search('alpine', 25)
- names, length = itertools.tee(actual)
-
- for img in names:
- self.assertIn('alpine', img.name)
- self.assertTrue(0 < len(list(length)) <= 25)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/contrib/python/podman/test/test_libs.py b/contrib/python/podman/test/test_libs.py
deleted file mode 100644
index 202bed1d8..000000000
--- a/contrib/python/podman/test/test_libs.py
+++ /dev/null
@@ -1,53 +0,0 @@
-import datetime
-import unittest
-
-import podman
-
-
-class TestLibs(unittest.TestCase):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
- def test_parse(self):
- expected = datetime.datetime.strptime(
- '2018-05-08T14:12:53.797795-0700', '%Y-%m-%dT%H:%M:%S.%f%z')
- for v in [
- '2018-05-08T14:12:53.797795191-07:00',
- '2018-05-08T14:12:53.797795-07:00',
- '2018-05-08T14:12:53.797795-0700',
- '2018-05-08 14:12:53.797795191 -0700 MST',
- ]:
- actual = podman.datetime_parse(v)
- self.assertEqual(actual, expected)
-
- expected = datetime.datetime.strptime(
- '2018-05-08T14:12:53.797795-0000', '%Y-%m-%dT%H:%M:%S.%f%z')
- for v in [
- '2018-05-08T14:12:53.797795191Z',
- '2018-05-08T14:12:53.797795191z',
- ]:
- actual = podman.datetime_parse(v)
- self.assertEqual(actual, expected)
-
- actual = podman.datetime_parse(datetime.datetime.now().isoformat())
- self.assertIsNotNone(actual)
-
- def test_parse_fail(self):
- for v in [
- 'There is no time here.',
- ]:
- with self.assertRaises(ValueError):
- podman.datetime_parse(v)
-
- def test_format(self):
- expected = '2018-05-08T18:24:52.753227-07:00'
- dt = podman.datetime_parse(expected)
- actual = podman.datetime_format(dt)
- self.assertEqual(actual, expected)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/contrib/python/podman/test/test_pods_ctnrs.py b/contrib/python/podman/test/test_pods_ctnrs.py
deleted file mode 100644
index 009e30720..000000000
--- a/contrib/python/podman/test/test_pods_ctnrs.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import os
-from test.podman_testcase import PodmanTestCase
-
-import podman
-from podman import FoldedString
-
-pod = None
-
-
-class TestPodsCtnrs(PodmanTestCase):
- @classmethod
- def setUpClass(cls):
- # Populate storage
- super().setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super().tearDownClass()
-
- def setUp(self):
- self.tmpdir = os.environ['TMPDIR']
- self.host = os.environ['PODMAN_HOST']
-
- self.pclient = podman.Client(self.host)
-
- def test_010_populate(self):
- global pod
-
- pod = self.pclient.pods.create('pod1')
- self.assertEqual('pod1', pod.name)
-
- img = self.pclient.images.get('docker.io/library/alpine:latest')
- ctnr = img.container(pod=pod.id)
-
- pod.refresh()
- self.assertEqual('1', pod.numberofcontainers)
- self.assertEqual(ctnr.id, pod.containersinfo[0]['id'])
-
- def test_015_one_shot(self):
- global pod
-
- details = pod.inspect()
- state = FoldedString(details.containers[0]['state'])
- self.assertEqual(state, 'configured')
-
- pod = pod.start()
- status = FoldedString(pod.containersinfo[0]['status'])
- # Race on whether container is still running or finished
- self.assertIn(status, ('stopped', 'exited', 'running'))
-
- pod = pod.restart()
- status = FoldedString(pod.containersinfo[0]['status'])
- self.assertIn(status, ('stopped', 'exited', 'running'))
-
- # Pod kill is broken, so use stop for now
- killed = pod.stop()
- self.assertEqual(pod, killed)
-
- def test_999_remove(self):
- global pod
-
- ident = pod.remove(force=True)
- self.assertEqual(ident, pod.id)
-
- with self.assertRaises(StopIteration):
- next(self.pclient.pods.list())
diff --git a/contrib/python/podman/test/test_pods_no_ctnrs.py b/contrib/python/podman/test/test_pods_no_ctnrs.py
deleted file mode 100644
index 48b4f74e4..000000000
--- a/contrib/python/podman/test/test_pods_no_ctnrs.py
+++ /dev/null
@@ -1,94 +0,0 @@
-import os
-import unittest
-
-import podman
-import varlink
-
-ident = None
-pod = None
-
-
-class TestPodsNoCtnrs(unittest.TestCase):
- def setUp(self):
- self.tmpdir = os.environ['TMPDIR']
- self.host = os.environ['PODMAN_HOST']
-
- self.pclient = podman.Client(self.host)
-
- def test_010_create(self):
- global ident
-
- actual = self.pclient.pods.create('pod0')
- self.assertIsNotNone(actual)
- ident = actual.id
-
- def test_015_list(self):
- global ident, pod
-
- actual = next(self.pclient.pods.list())
- self.assertEqual('pod0', actual.name)
- self.assertEqual(ident, actual.id)
- self.assertEqual('Created', actual.status)
- self.assertEqual('0', actual.numberofcontainers)
- self.assertFalse(actual.containersinfo)
- pod = actual
-
- def test_020_get(self):
- global ident, pod
-
- actual = self.pclient.pods.get(pod.id)
- self.assertEqual('pod0', actual.name)
- self.assertEqual(ident, actual.id)
- self.assertEqual('Created', actual.status)
- self.assertEqual('0', actual.numberofcontainers)
- self.assertFalse(actual.containersinfo)
-
- def test_025_inspect(self):
- global ident, pod
-
- details = pod.inspect()
- self.assertEqual(ident, details.id)
- self.assertEqual('pod0', details.config['name'])
- self.assertIsNone(details.containers)
-
- def test_030_ident_no_ctnrs(self):
- global ident, pod
-
- actual = pod.kill()
- self.assertEqual(pod, actual)
-
- actual = pod.pause()
- self.assertEqual(pod, actual)
-
- actual = pod.unpause()
- self.assertEqual(pod, actual)
-
- actual = pod.stop()
- self.assertEqual(pod, actual)
-
- def test_045_raises_no_ctnrs(self):
- global ident, pod
-
- with self.assertRaises(podman.NoContainersInPod):
- pod.start()
-
- with self.assertRaises(podman.NoContainersInPod):
- pod.restart()
-
- with self.assertRaises(podman.NoContainerRunning):
- next(pod.stats())
-
- with self.assertRaises(varlink.error.MethodNotImplemented):
- pod.top()
-
- with self.assertRaises(varlink.error.MethodNotImplemented):
- pod.wait()
-
- def test_999_remove(self):
- global ident, pod
-
- actual = pod.remove()
- self.assertEqual(ident, actual)
-
- with self.assertRaises(StopIteration):
- next(self.pclient.pods.list())
diff --git a/contrib/python/podman/test/test_runner.sh b/contrib/python/podman/test/test_runner.sh
deleted file mode 100755
index 651b2e74f..000000000
--- a/contrib/python/podman/test/test_runner.sh
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/bin/bash
-
-# podman needs to play some games with resources
-if [[ $(id -u) != 0 ]]; then
- echo >&2 $0 must be run as root.
- exit 2
-fi
-
-# setup path to find new binaries _NOT_ system binaries
-if [[ ! -x ../../../bin/podman ]]; then
- echo 1>&2 Cannot find podman binary from libpod root directory. Run \"make binaries\"
- exit 1
-fi
-export PATH=../../../bin:$PATH
-
-function usage {
- echo 1>&2 $0 '[-v] [-h] [test.<TestCase>|test.<TestCase>.<step>]'
-}
-
-while getopts "vh" arg; do
- case $arg in
- v ) VERBOSE='-v'; export LOG_LEVEL=debug ;;
- h ) usage ; exit 0 ;;
- \? ) usage ; exit 2 ;;
- esac
-done
-shift $((OPTIND -1))
-
-function cleanup {
- set +xeuo pipefail
- # aggressive cleanup as tests may crash leaving crap around
- umount '^(shm|nsfs)'
- umount '\/run\/netns'
- if [[ $RETURNCODE -eq 0 ]]; then
- rm -r "$1"
- fi
-}
-
-# Create temporary directory for storage
-export TMPDIR=`mktemp -d /tmp/podman.XXXXXXXXXX`
-trap "cleanup $TMPDIR" EXIT
-
-function umount {
- set +xeuo pipefail
- # xargs -r always ran once, so write any mount points to file first
- mount |awk "/$1/"' { print $3 }' >${TMPDIR}/mounts
- if [[ -s ${TMPDIR}/mounts ]]; then
- xargs <${TMPDIR}/mounts -t umount
- fi
-}
-
-function showlog {
- [[ -s $1 ]] && cat <<-EOT
-$1 =====
-$(cat "$1")
-
-EOT
-}
-
-# Need locations to store stuff
-mkdir -p ${TMPDIR}/{podman,crio,crio-run,cni/net.d,ctnr,tunnel}
-
-# Cannot be done in python unittest fixtures. EnvVar not picked up.
-export REGISTRIES_CONFIG_PATH=${TMPDIR}/registry.conf
-cat >$REGISTRIES_CONFIG_PATH <<-EOT
- [registries.search]
- registries = ['docker.io']
- [registries.insecure]
- registries = []
- [registries.block]
- registries = []
-EOT
-
-export CNI_CONFIG_PATH=${TMPDIR}/cni/net.d
-cat >$CNI_CONFIG_PATH/87-podman-bridge.conflist <<-EOT
-{
- "cniVersion": "0.3.0",
- "name": "podman",
- "plugins": [{
- "type": "bridge",
- "bridge": "cni0",
- "isGateway": true,
- "ipMasq": true,
- "ipam": {
- "type": "host-local",
- "subnet": "10.88.0.0/16",
- "routes": [{
- "dst": "0.0.0.0/0"
- }]
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- }
- ]
-}
-EOT
-
-cat >$TMPDIR/ctnr/hello.sh <<-EOT
-echo 'Hello, World'
-exit 0
-EOT
-
-cat >$TMPDIR/ctnr/Dockerfile <<-EOT
-FROM alpine:latest
-COPY ./hello.sh /tmp/
-RUN chmod 755 /tmp/hello.sh
-ENTRYPOINT ["/tmp/hello.sh"]
-EOT
-
-export PODMAN_HOST="unix:${TMPDIR}/podman/io.podman"
-PODMAN_ARGS="--storage-driver=vfs \
- --root=${TMPDIR}/crio \
- --runroot=${TMPDIR}/crio-run \
- --cni-config-dir=$CNI_CONFIG_PATH \
- --cgroup-manager=cgroupfs \
- "
-if [[ -n $VERBOSE ]]; then
- PODMAN_ARGS="$PODMAN_ARGS --log-level=$LOG_LEVEL"
-fi
-PODMAN="podman $PODMAN_ARGS"
-
-cat <<-EOT |tee /tmp/test_podman.output
-$($PODMAN --version)
-$PODMAN varlink --timeout=0 ${PODMAN_HOST}
-==========================================
-EOT
-
-# Run podman in background without systemd for test purposes
-$PODMAN varlink --timeout=0 ${PODMAN_HOST} >>/tmp/test_podman.output 2>&1 &
-if [[ $? != 0 ]]; then
- echo 1>&2 Failed to start podman
- showlog /tmp/test_podman.output
-fi
-
-if [[ -z $1 ]]; then
- export PYTHONPATH=.
- python3 -m unittest discover -s . $VERBOSE
- RETURNCODE=$?
-else
- export PYTHONPATH=.:./test
- python3 -m unittest $1 $VERBOSE
- RETURNCODE=$?
-fi
-
-pkill -9 podman
-pkill -9 conmon
-
-showlog /tmp/test_podman.output
-showlog /tmp/alpine.log
-showlog /tmp/busybox.log
-
-exit $RETURNCODE
diff --git a/contrib/python/podman/test/test_system.py b/contrib/python/podman/test/test_system.py
deleted file mode 100644
index c483f3232..000000000
--- a/contrib/python/podman/test/test_system.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import os
-import unittest
-from urllib.parse import urlparse
-
-import podman
-import varlink
-
-
-class TestSystem(unittest.TestCase):
- def setUp(self):
- self.host = os.environ['PODMAN_HOST']
- self.tmpdir = os.environ['TMPDIR']
-
- def tearDown(self):
- pass
-
- def test_bad_address(self):
- with self.assertRaisesRegex(varlink.client.ConnectionError,
- "Invalid address 'bad address'"):
- podman.Client('bad address')
-
- def test_ping(self):
- with podman.Client(self.host) as pclient:
- self.assertTrue(pclient.system.ping())
-
- @unittest.skip("TODO: Need to setup ssh under Travis")
- def test_remote_ping(self):
- host = urlparse(self.host)
- remote_uri = 'ssh://root@localhost{}'.format(host.path)
-
- local_uri = 'unix:{}/tunnel/podman.sock'.format(self.tmpdir)
- with podman.Client(
- uri=local_uri,
- remote_uri=remote_uri,
- identity_file=os.path.expanduser('~/.ssh/id_rsa'),
- ) as remote_client:
- self.assertTrue(remote_client.system.ping())
-
- def test_versions(self):
- with podman.Client(self.host) as pclient:
- # Values change with each build so we cannot test too much
- self.assertListEqual(
- sorted([
- 'built', 'client_version', 'git_commit', 'go_version',
- 'os_arch', 'version'
- ]), sorted(list(pclient.system.versions._fields)))
- pclient.system.versions
- self.assertIsNot(podman.__version__, '0.0.0')
-
- def test_info(self):
- with podman.Client(self.host) as pclient:
- actual = pclient.system.info()
- # Values change too much to do exhaustive testing
- self.assertIsNotNone(actual.podman['go_version'])
- self.assertListEqual(
- sorted([
- 'host', 'insecure_registries', 'podman', 'registries',
- 'store'
- ]), sorted(list(actual._fields)))
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/contrib/python/podman/test/test_tunnel.py b/contrib/python/podman/test/test_tunnel.py
deleted file mode 100644
index 9a33e76cd..000000000
--- a/contrib/python/podman/test/test_tunnel.py
+++ /dev/null
@@ -1,86 +0,0 @@
-from __future__ import absolute_import
-
-import logging
-import time
-import unittest
-from unittest.mock import MagicMock, patch
-
-from podman.libs.tunnel import Context, Portal, Tunnel
-
-
-class TestTunnel(unittest.TestCase):
- def setUp(self):
- self.tunnel_01 = MagicMock(spec=Tunnel)
- self.tunnel_02 = MagicMock(spec=Tunnel)
-
- def test_portal_ops(self):
- portal = Portal(sweap=500)
- portal['unix:/01'] = self.tunnel_01
- portal['unix:/02'] = self.tunnel_02
-
- self.assertEqual(portal.get('unix:/01'), self.tunnel_01)
- self.assertEqual(portal.get('unix:/02'), self.tunnel_02)
-
- del portal['unix:/02']
- with self.assertRaises(KeyError):
- portal['unix:/02']
- self.assertEqual(len(portal), 1)
-
- def test_portal_reaping(self):
- portal = Portal(sweap=0.5)
- portal['unix:/01'] = self.tunnel_01
- portal['unix:/02'] = self.tunnel_02
-
- self.assertEqual(len(portal), 2)
- for entry in portal:
- self.assertIn(entry, (self.tunnel_01, self.tunnel_02))
-
- time.sleep(1)
- portal.reap()
- self.assertEqual(len(portal), 0)
-
- def test_portal_no_reaping(self):
- portal = Portal(sweap=500)
- portal['unix:/01'] = self.tunnel_01
- portal['unix:/02'] = self.tunnel_02
-
- portal.reap()
- self.assertEqual(len(portal), 2)
- for entry in portal:
- self.assertIn(entry, (self.tunnel_01, self.tunnel_02))
-
- @patch('subprocess.Popen')
- @patch('os.path.exists', return_value=True)
- @patch('weakref.finalize')
- def test_tunnel(self, mock_finalize, mock_exists, mock_Popen):
- mock_Popen.return_value.returncode = 0
-
- context = Context(
- 'unix:/01',
- 'io.podman',
- '/tmp/user/socket',
- '/run/podman/socket',
- 'user',
- 'hostname',
- None,
- '~/.ssh/id_rsa',
- )
- tunnel = Tunnel(context).bore()
-
- cmd = ['ssh', '-fNT']
- if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
- cmd.append('-v')
- else:
- cmd.append('-q')
-
- cmd.extend((
- '-L',
- '{}:{}'.format(context.local_socket, context.remote_socket),
- '-i',
- context.identity_file,
- '{}@{}'.format(context.username, context.hostname),
- ))
-
- mock_finalize.assert_called_once_with(tunnel, tunnel.close)
- mock_exists.assert_called_once_with(context.local_socket)
- mock_Popen.assert_called_once_with(cmd, close_fds=True)
diff --git a/contrib/python/podman/tox.ini b/contrib/python/podman/tox.ini
deleted file mode 100644
index 797eafbe3..000000000
--- a/contrib/python/podman/tox.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[tox]
-envlist = py34,py35,py36
-skipdist = True
-
-[testenv]
-deps=-rrequirements.txt
-whitelist_externals = bash
-commands=bash test/test_runner.sh
diff --git a/contrib/python/pypodman/.pylintrc b/contrib/python/pypodman/.pylintrc
deleted file mode 100644
index a5628a6cf..000000000
--- a/contrib/python/pypodman/.pylintrc
+++ /dev/null
@@ -1,564 +0,0 @@
-[MASTER]
-
-# A comma-separated list of package or module names from where C extensions may
-# be loaded. Extensions are loading into the active Python interpreter and may
-# run arbitrary code.
-extension-pkg-whitelist=
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=CVS
-
-# Add files or directories matching the regex patterns to the blacklist. The
-# regex matches against base names, not paths.
-ignore-patterns=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
-# number of processors available to use.
-jobs=0
-
-# Control the amount of potential inferred values when inferring a single
-# object. This can help the performance when dealing with large functions or
-# complex, nested conditions.
-limit-inference-results=100
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-# Pickle collected data for later comparisons.
-persistent=yes
-
-# Specify a configuration file.
-#rcfile=
-
-# When enabled, pylint would attempt to guess common misconfiguration and emit
-# user-friendly hints instead of false-positive error messages.
-suggestion-mode=yes
-
-# Allow loading of arbitrary C extensions. Extensions are imported into the
-# active Python interpreter and may run arbitrary code.
-unsafe-load-any-extension=no
-
-
-[MESSAGES CONTROL]
-
-# Only show warnings with the listed confidence levels. Leave empty to show
-# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
-confidence=
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifiers separated by comma (,) or put this
-# option multiple times (only on the command line, not in the configuration
-# file where it should appear only once). You can also use "--disable=all" to
-# disable everything first and then reenable specific checks. For example, if
-# you want to run only the similarities checker, you can use "--disable=all
-# --enable=similarities". If you want to run only the classes checker, but have
-# no Warning level messages displayed, use "--disable=all --enable=classes
-# --disable=W".
-disable=print-statement,
- parameter-unpacking,
- unpacking-in-except,
- old-raise-syntax,
- backtick,
- long-suffix,
- old-ne-operator,
- old-octal-literal,
- import-star-module-level,
- non-ascii-bytes-literal,
- raw-checker-failed,
- bad-inline-option,
- locally-disabled,
- locally-enabled,
- file-ignored,
- suppressed-message,
- useless-suppression,
- deprecated-pragma,
- use-symbolic-message-instead,
- apply-builtin,
- basestring-builtin,
- buffer-builtin,
- cmp-builtin,
- coerce-builtin,
- execfile-builtin,
- file-builtin,
- long-builtin,
- raw_input-builtin,
- reduce-builtin,
- standarderror-builtin,
- unicode-builtin,
- xrange-builtin,
- coerce-method,
- delslice-method,
- getslice-method,
- setslice-method,
- no-absolute-import,
- old-division,
- dict-iter-method,
- dict-view-method,
- next-method-called,
- metaclass-assignment,
- indexing-exception,
- raising-string,
- reload-builtin,
- oct-method,
- hex-method,
- nonzero-method,
- cmp-method,
- input-builtin,
- round-builtin,
- intern-builtin,
- unichr-builtin,
- map-builtin-not-iterating,
- zip-builtin-not-iterating,
- range-builtin-not-iterating,
- filter-builtin-not-iterating,
- using-cmp-argument,
- eq-without-hash,
- div-method,
- idiv-method,
- rdiv-method,
- exception-message-attribute,
- invalid-str-codec,
- sys-max-int,
- bad-python3-import,
- deprecated-string-function,
- deprecated-str-translate-call,
- deprecated-itertools-function,
- deprecated-types-field,
- next-method-defined,
- dict-items-not-iterating,
- dict-keys-not-iterating,
- dict-values-not-iterating,
- deprecated-operator-function,
- deprecated-urllib-function,
- xreadlines-attribute,
- deprecated-sys-function,
- exception-escape,
- comprehension-escape
-
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time (only on the command line, not in the configuration file where
-# it should appear only once). See also the "--disable" option for examples.
-enable=c-extension-no-member
-
-
-[REPORTS]
-
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Template used to display messages. This is a python new-style format string
-# used to format the message information. See doc for all details.
-#msg-template=
-
-# Set the output format. Available formats are text, parseable, colorized, json
-# and msvs (visual studio). You can also give a reporter class, e.g.
-# mypackage.mymodule.MyReporterClass.
-output-format=text
-
-# Tells whether to display a full report or only the messages.
-reports=no
-
-# Activate the evaluation score.
-score=yes
-
-
-[REFACTORING]
-
-# Maximum number of nested blocks for function / method body
-max-nested-blocks=5
-
-# Complete name of functions that never returns. When checking for
-# inconsistent-return-statements if a never returning function is called then
-# it will be considered as an explicit return statement and no message will be
-# printed.
-never-returning-functions=sys.exit
-
-
-[TYPECHECK]
-
-# List of decorators that produce context managers, such as
-# contextlib.contextmanager. Add to this list to register other decorators that
-# produce valid context managers.
-contextmanager-decorators=contextlib.contextmanager
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E1101 when accessed. Python regular
-# expressions are accepted.
-generated-members=
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# Tells whether to warn about missing members when the owner of the attribute
-# is inferred to be None.
-ignore-none=yes
-
-# This flag controls whether pylint should warn about no-member and similar
-# checks whenever an opaque object is returned when inferring. The inference
-# can return multiple potential results while evaluating a Python object, but
-# some branches might not be evaluated, which results in partial inference. In
-# that case, it might be useful to still emit no-member and other checks for
-# the rest of the inferred objects.
-ignore-on-opaque-inference=yes
-
-# List of class names for which member attributes should not be checked (useful
-# for classes with dynamically set attributes). This supports the use of
-# qualified names.
-ignored-classes=optparse.Values,thread._local,_thread._local
-
-# List of module names for which member attributes should not be checked
-# (useful for modules/projects where namespaces are manipulated during runtime
-# and thus existing member attributes cannot be deduced by static analysis. It
-# supports qualified module names, as well as Unix pattern matching.
-ignored-modules=
-
-# Show a hint with possible names when a member name was not found. The aspect
-# of finding the hint is based on edit distance.
-missing-member-hint=yes
-
-# The minimum edit distance a name should have in order to be considered a
-# similar match for a missing member name.
-missing-member-hint-distance=1
-
-# The total number of similar names that should be taken in consideration when
-# showing a hint for a missing member.
-missing-member-max-choices=1
-
-
-[SPELLING]
-
-# Limits count of emitted suggestions for spelling mistakes.
-max-spelling-suggestions=4
-
-# Spelling dictionary name. Available dictionaries: none. To make it working
-# install python-enchant package..
-spelling-dict=
-
-# List of comma separated words that should not be checked.
-spelling-ignore-words=
-
-# A path to a file that contains private dictionary; one word per line.
-spelling-private-dict-file=
-
-# Tells whether to store unknown words to indicated private dictionary in
-# --spelling-private-dict-file option instead of raising a message.
-spelling-store-unknown-words=no
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,
- XXX,
- TODO
-
-
-[FORMAT]
-
-# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
-expected-line-ending-format=
-
-# Regexp for a line that is allowed to be longer than the limit.
-ignore-long-lines=^\s*(# )?<?https?://\S+>?$
-
-# Number of spaces of indent required inside a hanging or continued line.
-indent-after-paren=4
-
-# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
-# tab).
-indent-string=' '
-
-# Maximum number of characters on a single line.
-max-line-length=100
-
-# Maximum number of lines in a module.
-max-module-lines=1000
-
-# List of optional constructs for which whitespace checking is disabled. `dict-
-# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
-# `trailing-comma` allows a space between comma and closing bracket: (a, ).
-# `empty-line` allows space-only lines.
-no-space-check=trailing-comma,
- dict-separator
-
-# Allow the body of a class to be on the same line as the declaration if body
-# contains single statement.
-single-line-class-stmt=no
-
-# Allow the body of an if to be on the same line as the test if there is no
-# else.
-single-line-if-stmt=no
-
-
-[BASIC]
-
-# Naming style matching correct argument names.
-#argument-naming-style=snake_case
-
-# Regular expression matching correct argument names. Overrides argument-
-# naming-style.
-argument-rgx=[a-z_][a-z0-9_]{1,30}$
-argument-name-hint=[a-z_][a-z0-9_]{1,30}$
-
-# Naming style matching correct attribute names.
-attr-naming-style=snake_case
-
-# Regular expression matching correct attribute names. Overrides attr-naming-
-# style.
-#attr-rgx=
-
-# Bad variable names which should always be refused, separated by a comma.
-bad-names=foo,
- bar,
- baz,
- toto,
- tutu,
- tata
-
-# Naming style matching correct class attribute names.
-class-attribute-naming-style=any
-
-# Regular expression matching correct class attribute names. Overrides class-
-# attribute-naming-style.
-#class-attribute-rgx=
-
-# Naming style matching correct class names.
-class-naming-style=PascalCase
-
-# Regular expression matching correct class names. Overrides class-naming-
-# style.
-#class-rgx=
-
-# Naming style matching correct constant names.
-const-naming-style=UPPER_CASE
-
-# Regular expression matching correct constant names. Overrides const-naming-
-# style.
-#const-rgx=
-
-# Minimum line length for functions/classes that require docstrings, shorter
-# ones are exempt.
-docstring-min-length=-1
-
-# Naming style matching correct function names.
-function-naming-style=snake_case
-
-# Regular expression matching correct function names. Overrides function-
-# naming-style.
-#function-rgx=
-
-# Good variable names which should always be accepted, separated by a comma.
-good-names=c,
- e,
- i,
- j,
- k,
- r,
- v,
- ex,
- Run,
- _
-
-# Include a hint for the correct naming format with invalid-name.
-include-naming-hint=no
-
-# Naming style matching correct inline iteration names.
-inlinevar-naming-style=any
-
-# Regular expression matching correct inline iteration names. Overrides
-# inlinevar-naming-style.
-#inlinevar-rgx=
-
-# Naming style matching correct method names.
-method-naming-style=snake_case
-
-# Regular expression matching correct method names. Overrides method-naming-
-# style.
-#method-rgx=
-
-# Naming style matching correct module names.
-module-naming-style=snake_case
-
-# Regular expression matching correct module names. Overrides module-naming-
-# style.
-#module-rgx=
-
-# Colon-delimited sets of names that determine each other's naming style when
-# the name regexes allow several styles.
-name-group=
-
-# Regular expression which should only match function or class names that do
-# not require a docstring.
-no-docstring-rgx=^_
-
-# List of decorators that produce properties, such as abc.abstractproperty. Add
-# to this list to register other decorators that produce valid properties.
-# These decorators are taken in consideration only for invalid-name.
-property-classes=abc.abstractproperty
-
-# Naming style matching correct variable names.
-#variable-naming-style=snake_case
-
-# Regular expression matching correct variable names. Overrides variable-
-# naming-style.
-variable-rgx=[a-z_][a-z0-9_]{2,30}$
-variable-name-hint=[a-z_][a-z0-9_]{2,30}$
-
-[SIMILARITIES]
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-# Ignore imports when computing similarities.
-ignore-imports=no
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-
-[VARIABLES]
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-# Tells whether unused global variables should be treated as a violation.
-allow-global-unused-variables=yes
-
-# List of strings which can identify a callback function by name. A callback
-# name must start or end with one of those strings.
-callbacks=cb_,
- _cb
-
-# A regular expression matching the name of dummy variables (i.e. expected to
-# not be used).
-dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore.
-ignored-argument-names=_.*|^ignored_|^unused_
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# List of qualified module names which can have objects that can redefine
-# builtins.
-redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
-
-
-[LOGGING]
-
-# Logging modules to check that the string format arguments are in logging
-# function parameter format.
-logging-modules=logging
-
-
-[IMPORTS]
-
-# Allow wildcard imports from modules that define __all__.
-allow-wildcard-with-all=no
-
-# Analyse import fallback blocks. This can be used to support both Python 2 and
-# 3 compatible code, which means that the block might have code that exists
-# only in one or another interpreter, leading to false positives when analysed.
-analyse-fallback-blocks=no
-
-# Deprecated modules which should not be used, separated by a comma.
-deprecated-modules=optparse,tkinter.tix
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled).
-ext-import-graph=
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled).
-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled).
-int-import-graph=
-
-# Force import order to recognize a module as part of the standard
-# compatibility libraries.
-known-standard-library=
-
-# Force import order to recognize a module as part of a third party library.
-known-third-party=enchant
-
-
-[DESIGN]
-
-# Support argparse.Action constructor API
-# Maximum number of arguments for function / method.
-max-args=12
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=7
-
-# Maximum number of boolean expressions in an if statement.
-max-bool-expr=5
-
-# Maximum number of branch for function / method body.
-max-branches=12
-
-# Maximum number of locals for function / method body.
-max-locals=15
-
-# Maximum number of parents for a class (see R0901).
-max-parents=10
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=20
-
-# Maximum number of return / yield for function / method body.
-max-returns=6
-
-# Maximum number of statements in function / method body.
-max-statements=50
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=2
-
-
-[CLASSES]
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,
- __new__,
- setUp
-
-# List of member names, which should be excluded from the protected access
-# warning.
-exclude-protected=_asdict,
- _fields,
- _replace,
- _source,
- _make
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-# List of valid names for the first argument in a metaclass class method.
-valid-metaclass-classmethod-first-arg=cls
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception".
-overgeneral-exceptions=Exception
diff --git a/contrib/python/pypodman/MANIFEST.in b/contrib/python/pypodman/MANIFEST.in
deleted file mode 100644
index 72e638cb9..000000000
--- a/contrib/python/pypodman/MANIFEST.in
+++ /dev/null
@@ -1,2 +0,0 @@
-prune test/
-include README.md
diff --git a/contrib/python/pypodman/Makefile b/contrib/python/pypodman/Makefile
deleted file mode 100644
index 230eee44d..000000000
--- a/contrib/python/pypodman/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-PYTHON ?= $(shell command -v python3 2>/dev/null || command -v python)
-DESTDIR := /
-PODMAN_VERSION ?= '0.11.1.1'
-
-.PHONY: python-pypodman
-python-pypodman:
- PODMAN_VERSION=$(PODMAN_VERSION) \
- $(PYTHON) setup.py sdist bdist
-
-.PHONY: lint
-lint:
- $(PYTHON) -m pylint pypodman
-
-.PHONY: integration
-integration:
- true
-
-.PHONY: install
-install:
- PODMAN_VERSION=$(PODMAN_VERSION) \
- $(PYTHON) setup.py install --root ${DESTDIR}
-
-.PHONY: upload
-upload:
- PODMAN_VERSION=$(PODMAN_VERSION) $(PYTHON) setup.py sdist bdist_wheel
- twine upload --repository-url https://test.pypi.org/legacy/ dist/*
-
-.PHONY: clobber
-clobber: uninstall clean
-
-.PHONY: uninstall
- $(PYTHON) -m pip uninstall --yes pypodman ||:
-
-.PHONY: clean
-clean:
- rm -rf pypodman.egg-info dist
- find . -depth -name __pycache__ -exec rm -rf {} \;
- find . -depth -name \*.pyc -exec rm -f {} \;
- $(PYTHON) ./setup.py clean --all
diff --git a/contrib/python/pypodman/README.md b/contrib/python/pypodman/README.md
deleted file mode 100644
index 6991daffa..000000000
--- a/contrib/python/pypodman/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# pypodman - CLI for podman written in python
-
-## Status: Active Development
-
-See [libpod](https://github.com/containers/libpod/contrib/python/pypodman)
-
-## Releases
-
-To build the pypodman egg and install as user:
-
-```sh
-cd ~/libpod/contrib/python/pypodman
-python3 setup.py clean -a && python3 setup.py sdist bdist
-python3 setup.py install --user
-```
-Add `~/.local/bin` to your `PATH` to run pypodman command.
-
-## Running command:
-
-### Against local podman service
-```sh
-$ pypodman images
-```
-### Against remote podman service
-```sh
-$ pypodman --host node001.example.org images
-```
-### Full help system available
-```sh
-$ pypodman -h
-```
-```sh
-$ pypodman images -h
-```
diff --git a/contrib/python/pypodman/docs/man1/pypodman.1 b/contrib/python/pypodman/docs/man1/pypodman.1
deleted file mode 100644
index 45472dab0..000000000
--- a/contrib/python/pypodman/docs/man1/pypodman.1
+++ /dev/null
@@ -1,101 +0,0 @@
-.TH pypodman 1 2018-07-20 0.7.3
-.SH NAME
-pypodman \- CLI management tool for containers and images
-.SH SYNOPSIS
-\f[B]pypodman\f[] [\f[I]global options\f[]] \f[I]command\f[] [\f[I]options\f[]]
-.SH DESCRIPTION
-pypodman is a simple client only tool to help with debugging issues when daemons
-such as CRI runtime and the kubelet are not responding or failing.
-.P
-pypodman uses a VarLink API to commicate with a podman service running on either
-the local or remote machine. pypodman uses ssh to create secure tunnels when
-communicating with a remote service.
-.SH GLOBAL OPTIONS
-.PP
-\f[B]\[en]help, \-h\f[]
-.PP
-Print usage statement.
-.PP
-\f[B]\[en]version\f[]
-.PP
-Print program version number and exit.
-.PP
-\f[B]\[en]config\-home\f[]
-.PP
-Directory that will be namespaced with \f[C]pypodman\f[] to hold
-\f[C]pypodman.conf\f[].
-See FILES below for more details.
-.PP
-\f[B]\[en]log\-level\f[]
-.PP
-Log events above specified level: DEBUG, INFO, WARNING (default), ERROR,
-or CRITICAL.
-.PP
-\f[B]\[en]run\-dir\f[]
-.PP
-Directory that will be namespaced with \f[C]pypodman\f[] to hold local socket
-bindings. The default is `\f[C]$XDG_RUNTIME_DIR\\\f[].
-.PP
-\f[B]\[en]user\f[]
-.PP
-Authenicating user on remote host. \f[C]pypodman\f[] defaults to the logged in
-user.
-.PP
-\f[B]\[en]host\f[]
-.PP
-Name of remote host. There is no default, if not given \f[C]pypodman\f[]
-attempts to connect to \f[C]\-\-remote\-socket\-path\f[] on local host.
-.PP
-\f[B]\[en]port\f[]
-.PP
-The optional port for \f[C]ssh\f[] to connect tunnel to on remote host.
-Default is None and will allow \f[C]ssh\f[] to follow it's default configuration.
-.PP
-\f[B]\[en]remote\-socket\-path\f[]
-.PP
-Path on remote host for podman service's \f[C]AF_UNIX\f[] socket. The default is
-\f[C]/run/podman/io.podman\f[].
-.PP
-\f[B]\[en]identity\-file\f[]
-.PP
-The optional \f[C]ssh\f[] identity file to authenicate when tunnelling to remote
-host. Default is None and will allow \f[C]ssh\f[] to follow it's default methods
-for resolving the identity and private key using the logged in user.
-.SH COMMANDS
-.PP
-See podman(1) (podman.1.md)
-.SH FILES
-.PP
-\f[B]pypodman/pypodman.conf\f[]
-(\f[C]Any\ element\ of\ XDG_CONFIG_DIRS\f[] and/or
-\f[C]XDG_CONFIG_HOME\f[] and/or \f[B]\[en]config\-home\f[])
-.PP
-pypodman.conf is one or more configuration files for running the pypodman
-command. pypodman.conf is a TOML file with the stanza \f[C][default]\f[], with a
-map of \f[C]option: value\f[].
-.PP
-pypodman follows the XDG (freedesktop.org) conventions for resolving it's
-configuration. The list below are read from top to bottom with later items
-overwriting earlier. Any missing items are ignored.
-.IP \[bu] 2
-\f[C]pypodman/pypodman.conf\f[] from any path element in
-\f[C]XDG_CONFIG_DIRS\f[] or \f[C]\\etc\\xdg\f[]
-.IP \[bu] 2
-\f[C]XDG_CONFIG_HOME\f[] or $HOME/.config + \f[C]pypodman/pypodman.conf\f[]
-.IP \[bu] 2
-From \f[C]\-\-config\-home\f[] command line option + \f[C]pypodman/pypodman.conf\f[]
-.IP \[bu] 2
-From environment variable prefixed with PODMAN_, for example: PODMAN_RUN_DIR
-.IP \[bu] 2
-From command line option, for example: \[en]run\-dir
-.PP
-This should provide Operators the ability to setup basic configurations
-and allow users to customize them.
-.PP
-\f[B]XDG_RUNTIME_DIR\f[] (\f[C]XDG_RUNTIME_DIR/io.podman\f[])
-.PP
-Directory where pypodman stores non\-essential runtime files and other file
-objects (such as sockets, named pipes, \&...).
-.SH SEE ALSO
-.PP
-\f[C]podman(1)\f[], \f[C]libpod(8)\f[]
diff --git a/contrib/python/pypodman/pypodman/__init__.py b/contrib/python/pypodman/pypodman/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/contrib/python/pypodman/pypodman/__init__.py
+++ /dev/null
diff --git a/contrib/python/pypodman/pypodman/lib/__init__.py b/contrib/python/pypodman/pypodman/lib/__init__.py
deleted file mode 100644
index d9a434254..000000000
--- a/contrib/python/pypodman/pypodman/lib/__init__.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""Remote podman client support library."""
-import sys
-
-import podman
-from pypodman.lib.action_base import AbstractActionBase
-from pypodman.lib.parser_actions import (ChangeAction, PathAction,
- PositiveIntAction, SignalAction,
- UnitAction)
-from pypodman.lib.podman_parser import PodmanArgumentParser
-from pypodman.lib.report import Report, ReportColumn
-
-# Silence pylint overlording...
-assert ChangeAction
-assert PathAction
-assert PositiveIntAction
-assert SignalAction
-assert UnitAction
-
-__all__ = [
- 'AbstractActionBase',
- 'PodmanArgumentParser',
- 'Report',
- 'ReportColumn',
-]
-
-
-def query_model(model, identifiers=None):
- """Retrieve all (default) or given model(s)."""
- objs = []
- if identifiers is None:
- objs.extend(model.list())
- else:
- try:
- for ident in identifiers:
- objs.append(model.get(ident))
- except (
- podman.PodNotFound,
- podman.ImageNotFound,
- podman.ContainerNotFound,
- ) as ex:
- print(
- '"{}" not found'.format(ex.name), file=sys.stderr, flush=True)
- return objs
diff --git a/contrib/python/pypodman/pypodman/lib/action_base.py b/contrib/python/pypodman/pypodman/lib/action_base.py
deleted file mode 100644
index 5cba7ac5c..000000000
--- a/contrib/python/pypodman/pypodman/lib/action_base.py
+++ /dev/null
@@ -1,79 +0,0 @@
-"""Base class for all actions of remote client."""
-import abc
-from functools import lru_cache
-
-import podman
-
-
-class AbstractActionBase(abc.ABC):
- """Base class for all actions of remote client."""
-
- @classmethod
- @abc.abstractmethod
- def subparser(cls, parent):
- """Define parser for this action. Subclasses must implement.
-
- API:
- Use set_defaults() to set attributes "class_" and "method". These will
- be invoked as class_(parsed_args).method()
- """
- parent.add_flag(
- '--all',
- help='list all items.')
- parent.add_flag(
- '--truncate',
- '--trunc',
- default=True,
- help="Truncate id's and other long fields.")
- parent.add_flag(
- '--heading',
- default=True,
- help='Include table headings in the output.')
- parent.add_flag(
- '--quiet',
- help='List only the IDs.')
-
- def __init__(self, args):
- """Construct class."""
- # Dump all unset arguments before transmitting to service
- self._args = args
- self.opts = {
- k: v
- for k, v in vars(self._args).items() if v is not None
- }
-
- @property
- def remote_uri(self):
- """URI for remote side of connection."""
- return self._args.remote_uri
-
- @property
- def local_uri(self):
- """URI for local side of connection."""
- return self._args.local_uri
-
- @property
- def identity_file(self):
- """Key for authenication."""
- return self._args.identity_file
-
- @property
- @lru_cache(maxsize=1)
- def client(self):
- """Podman remote client for communicating."""
- if self._args.host is None:
- return podman.Client(uri=self.local_uri)
- return podman.Client(
- uri=self.local_uri,
- remote_uri=self.remote_uri,
- identity_file=self.identity_file)
-
- def __repr__(self):
- """Compute the “official” string representation of object."""
- return ("{}(local_uri='{}', remote_uri='{}',"
- " identity_file='{}')").format(
- self.__class__,
- self.local_uri,
- self.remote_uri,
- self.identity_file,
- )
diff --git a/contrib/python/pypodman/pypodman/lib/actions/__init__.py b/contrib/python/pypodman/pypodman/lib/actions/__init__.py
deleted file mode 100644
index c0d77ddb1..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/__init__.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""Module to export all the podman subcommands."""
-from pypodman.lib.actions.attach_action import Attach
-from pypodman.lib.actions.commit_action import Commit
-from pypodman.lib.actions.create_action import Create
-from pypodman.lib.actions.export_action import Export
-from pypodman.lib.actions.history_action import History
-from pypodman.lib.actions.images_action import Images
-from pypodman.lib.actions.import_action import Import
-from pypodman.lib.actions.info_action import Info
-from pypodman.lib.actions.inspect_action import Inspect
-from pypodman.lib.actions.kill_action import Kill
-from pypodman.lib.actions.logs_action import Logs
-from pypodman.lib.actions.mount_action import Mount
-from pypodman.lib.actions.pause_action import Pause
-from pypodman.lib.actions.pod_action import Pod
-from pypodman.lib.actions.port_action import Port
-from pypodman.lib.actions.ps_action import Ps
-from pypodman.lib.actions.pull_action import Pull
-from pypodman.lib.actions.push_action import Push
-from pypodman.lib.actions.restart_action import Restart
-from pypodman.lib.actions.rm_action import Rm
-from pypodman.lib.actions.rmi_action import Rmi
-from pypodman.lib.actions.run_action import Run
-from pypodman.lib.actions.search_action import Search
-from pypodman.lib.actions.start_action import Start
-from pypodman.lib.actions.version_action import Version
-
-__all__ = [
- 'Attach',
- 'Commit',
- 'Create',
- 'Export',
- 'History',
- 'Images',
- 'Import',
- 'Info',
- 'Inspect',
- 'Kill',
- 'Logs',
- 'Mount',
- 'Pause',
- 'Pod',
- 'Port',
- 'Ps',
- 'Pull',
- 'Push',
- 'Restart',
- 'Rm',
- 'Rmi',
- 'Run',
- 'Search',
- 'Start',
- 'Version',
-]
diff --git a/contrib/python/pypodman/pypodman/lib/actions/_create_args.py b/contrib/python/pypodman/pypodman/lib/actions/_create_args.py
deleted file mode 100644
index 8ab4292e8..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/_create_args.py
+++ /dev/null
@@ -1,401 +0,0 @@
-"""Implement common create container arguments together."""
-
-from pypodman.lib import SignalAction, UnitAction
-
-
-class CreateArguments():
- """Helper to add all the create flags to a command."""
-
- @classmethod
- def add_arguments(cls, parser):
- """Add CreateArguments to parser."""
- parser.add_argument(
- '--add-host',
- action='append',
- metavar='HOST',
- help='Add a line to /etc/hosts.'
- ' The option can be set multiple times.'
- ' (format: hostname:ip)')
- parser.add_argument(
- '--annotation',
- action='append',
- help='Add an annotation to the container.'
- 'The option can be set multiple times.'
- '(format: key=value)')
- parser.add_argument(
- '--attach',
- '-a',
- action='append',
- metavar='FD',
- help=('Attach to STDIN, STDOUT or STDERR. The option can be set'
- ' for each of stdin, stdout, and stderr.'))
- parser.add_argument(
- '--blkio-weight',
- choices=range(10, 1000),
- metavar='[10-1000]',
- help=('Block IO weight (relative weight) accepts a'
- ' weight value between 10 and 1000.'))
- parser.add_argument(
- '--blkio-weight-device',
- action='append',
- metavar='WEIGHT',
- help='Block IO weight, relative device weight.'
- ' (format: DEVICE_NAME:WEIGHT)')
- parser.add_argument(
- '--cap-add',
- action='append',
- metavar='CAP',
- help=('Add Linux capabilities'
- 'The option can be set multiple times.'))
- parser.add_argument(
- '--cap-drop',
- action='append',
- metavar='CAP',
- help=('Drop Linux capabilities'
- 'The option can be set multiple times.'))
- parser.add_argument(
- '--cgroup-parent',
- metavar='PATH',
- help='Path to cgroups under which the cgroup for the'
- ' container will be created. If the path is not'
- ' absolute, the path is considered to be relative'
- ' to the cgroups path of the init process. Cgroups'
- ' will be created if they do not already exist.')
- parser.add_argument(
- '--cidfile',
- metavar='PATH',
- help='Write the container ID to the file, on the remote host.')
- parser.add_argument(
- '--conmon-pidfile',
- metavar='PATH',
- help=('Write the pid of the conmon process to a file,'
- ' on the remote host.'))
- parser.add_argument(
- '--cpu-period',
- type=int,
- metavar='PERIOD',
- help=('Limit the CPU CFS (Completely Fair Scheduler) period.'))
- parser.add_argument(
- '--cpu-quota',
- type=int,
- metavar='QUOTA',
- help=('Limit the CPU CFS (Completely Fair Scheduler) quota.'))
- parser.add_argument(
- '--cpu-rt-period',
- type=int,
- metavar='PERIOD',
- help=('Limit the CPU real-time period in microseconds.'))
- parser.add_argument(
- '--cpu-rt-runtime',
- type=int,
- metavar='LIMIT',
- help=('Limit the CPU real-time runtime in microseconds.'))
- parser.add_argument(
- '--cpu-shares',
- type=int,
- metavar='SHARES',
- help=('CPU shares (relative weight)'))
- parser.add_argument(
- '--cpus',
- type=float,
- help=('Number of CPUs. The default is 0.0 which means no limit'))
- parser.add_argument(
- '--cpuset-cpus',
- metavar='LIST',
- help=('CPUs in which to allow execution (0-3, 0,1)'))
- parser.add_argument(
- '--cpuset-mems',
- metavar='NODES',
- help=('Memory nodes (MEMs) in which to allow execution (0-3, 0,1).'
- ' Only effective on NUMA systems'))
- parser.add_flag(
- '--detach',
- '-d',
- help='Detached mode: run the container in the background and'
- ' print the new container ID. (default: False)')
- parser.add_argument(
- '--detach-keys',
- metavar='KEY(s)',
- default=4,
- help='Override the key sequence for detaching a container.'
- ' (format: a single character [a-Z] or ctrl-<value> where'
- ' <value> is one of: a-z, @, ^, [, , or _)')
- parser.add_argument(
- '--device',
- action='append',
- help=('Add a host device to the container'
- 'The option can be set multiple times.'),
- )
- parser.add_argument(
- '--device-read-bps',
- action='append',
- metavar='LIMIT',
- help=('Limit read rate (bytes per second) from a device'
- ' (e.g. --device-read-bps=/dev/sda:1mb)'
- 'The option can be set multiple times.'),
- )
- parser.add_argument(
- '--device-read-iops',
- action='append',
- metavar='LIMIT',
- help=('Limit read rate (IO per second) from a device'
- ' (e.g. --device-read-iops=/dev/sda:1000)'
- 'The option can be set multiple times.'),
- )
- parser.add_argument(
- '--device-write-bps',
- action='append',
- metavar='LIMIT',
- help=('Limit write rate (bytes per second) to a device'
- ' (e.g. --device-write-bps=/dev/sda:1mb)'
- 'The option can be set multiple times.'),
- )
- parser.add_argument(
- '--device-write-iops',
- action='append',
- metavar='LIMIT',
- help=('Limit write rate (IO per second) to a device'
- ' (e.g. --device-write-iops=/dev/sda:1000)'
- 'The option can be set multiple times.'),
- )
- parser.add_argument(
- '--dns',
- action='append',
- metavar='SERVER',
- help=('Set custom DNS servers.'
- 'The option can be set multiple times.'),
- )
- parser.add_argument(
- '--dns-option',
- action='append',
- metavar='OPT',
- help=('Set custom DNS options.'
- 'The option can be set multiple times.'),
- )
- parser.add_argument(
- '--dns-search',
- action='append',
- metavar='DOMAIN',
- help=('Set custom DNS search domains.'
- 'The option can be set multiple times.'),
- )
- parser.add_argument(
- '--entrypoint',
- help=('Overwrite the default ENTRYPOINT of the image.'),
- )
- parser.add_argument(
- '--env',
- '-e',
- action='append',
- help=('Set environment variables.'),
- )
- parser.add_argument(
- '--env-file',
- help=('Read in a line delimited file of environment variables,'
- ' on the remote host.'),
- )
- parser.add_argument(
- '--expose',
- action='append',
- metavar='RANGE',
- help=('Expose a port, or a range of ports'
- ' (e.g. --expose=3300-3310) to set up port redirection.'),
- )
- parser.add_argument(
- '--gidmap',
- metavar='MAP',
- action='append',
- help=('GID map for the user namespace'),
- )
- parser.add_argument(
- '--group-add',
- action='append',
- metavar='GROUP',
- help=('Add additional groups to run as'))
- parser.add_argument('--hostname', help='Container host name')
-
- # only way for argparse to handle these options.
- vol_args = {
- 'choices': ('bind', 'tmpfs', 'ignore'),
- 'metavar': 'MODE',
- 'type': str.lower,
- 'help': 'Tells podman how to handle the builtin image volumes',
- }
-
- volume_group = parser.add_mutually_exclusive_group()
- volume_group.add_argument('--image-volume', **vol_args)
- volume_group.add_argument('--builtin-volume', **vol_args)
-
- parser.add_flag(
- '--interactive',
- '-i',
- help='Keep STDIN open even if not attached.')
- parser.add_argument('--ipc', help='Create namespace')
- parser.add_argument(
- '--kernel-memory', action=UnitAction, help='Kernel memory limit')
- parser.add_argument(
- '--label',
- '-l',
- action='append',
- help=('Add metadata to a container'
- ' (e.g., --label com.example.key=value)'))
- parser.add_argument(
- '--label-file', help='Read in a line delimited file of labels')
- parser.add_argument(
- '--log-driver',
- choices='json-file',
- metavar='json-file',
- default='json-file',
- help='Logging driver for the container. (default: %(default)s)')
- parser.add_argument(
- '--log-opt',
- action='append',
- help='Logging driver specific options')
- parser.add_argument(
- '--memory', '-m', action=UnitAction, help='Memory limit')
- parser.add_argument(
- '--memory-reservation',
- action=UnitAction,
- help='Memory soft limit')
- parser.add_argument(
- '--memory-swap',
- action=UnitAction,
- help=('A limit value equal to memory plus swap.'
- 'Must be used with the --memory flag'))
- parser.add_argument(
- '--memory-swappiness',
- choices=range(0, 100),
- metavar='[0-100]',
- help="Tune a container's memory swappiness behavior")
- parser.add_argument('--name', help='Assign a name to the container')
- parser.add_argument(
- '--network',
- '--net',
- metavar='BRIDGE',
- help='Set the Network mode for the container.'
- ' (format: bridge, host, container:UUID, ns:PATH, none)')
- parser.add_flag(
- '--oom-kill-disable',
- help='Whether to disable OOM Killer for the container or not.')
- parser.add_argument(
- '--oom-score-adj',
- choices=range(-1000, 1000),
- metavar='[-1000-1000]',
- help="Tune the host's OOM preferences for containers")
- parser.add_argument(
- '--pid',
- help='Set the PID Namespace mode for the container.'
- '(format: host, container:UUID, ns:PATH)')
- parser.add_argument(
- '--pids-limit',
- type=int,
- metavar='LIMIT',
- help=("Tune the container's pids limit."
- " Set -1 to have unlimited pids for the container."))
- parser.add_argument('--pod', help='Run container in an existing pod')
- parser.add_flag(
- '--privileged',
- help='Give extended privileges to this container.')
- parser.add_argument(
- '--publish',
- '-p',
- metavar='RANGE',
- help="Publish a container's port, or range of ports, to the host")
- parser.add_flag(
- '--publish-all',
- '-P',
- help='Publish all exposed ports to random'
- ' ports on the host interfaces.')
- parser.add_flag(
- '--quiet',
- '-q',
- help='Suppress output information when pulling images')
- parser.add_flag(
- '--read-only',
- help="Mount the container's root filesystem as read only.")
- parser.add_flag(
- '--rm',
- help='Automatically remove the container when it exits.')
- parser.add_argument(
- '--rootfs',
- help='If specified, the first argument refers to an'
- ' exploded container on the file system of remote host.')
- parser.add_argument(
- '--security-opt',
- action='append',
- metavar='OPT',
- help='Set security options.')
- parser.add_argument(
- '--shm-size', action=UnitAction, help='Size of /dev/shm')
- parser.add_flag(
- '--sig-proxy',
- help='Proxy signals sent to the podman run'
- ' command to the container process')
- parser.add_argument(
- '--stop-signal',
- action=SignalAction,
- default='TERM',
- help='Signal to stop a container')
- parser.add_argument(
- '--stop-timeout',
- metavar='TIMEOUT',
- type=int,
- default=10,
- help='Seconds to wait on stopping container.')
- parser.add_argument(
- '--subgidname',
- metavar='MAP',
- help='Name for GID map from the /etc/subgid file')
- parser.add_argument(
- '--subuidname',
- metavar='MAP',
- help='Name for UID map from the /etc/subuid file')
- parser.add_argument(
- '--sysctl',
- action='append',
- help='Configure namespaced kernel parameters at runtime')
- parser.add_argument(
- '--tmpfs',
- action='append',
- metavar='MOUNT',
- help='Create a tmpfs mount.'
- ' (default: rw,noexec,nosuid,nodev,size=65536k.)')
- parser.add_flag(
- '--tty',
- '-t',
- help='Allocate a pseudo-TTY for standard input of container.')
- parser.add_argument(
- '--uidmap',
- action='append',
- metavar='MAP',
- help='UID map for the user namespace')
- parser.add_argument(
- '--ulimit',
- action='append',
- metavar='OPT',
- help='Ulimit options',
- )
- parser.add_argument(
- '--user',
- '-u',
- help='Sets the username or UID used and optionally'
- ' the groupname or GID for the specified command.')
- parser.add_argument(
- '--userns',
- metavar='NAMESPACE',
- help='Set the user namespace mode for the container')
- parser.add_argument(
- '--uts',
- choices=('host', 'ns'),
- type=str.lower,
- help='Set the UTS mode for the container')
- parser.add_argument('--volume', '-v', help='Create a bind mount.')
- parser.add_argument(
- '--volumes-from',
- action='append',
- help='Mount volumes from the specified container(s).')
- parser.add_argument(
- '--workdir',
- '-w',
- metavar='PATH',
- help='Working directory inside the container')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/attach_action.py b/contrib/python/pypodman/pypodman/lib/actions/attach_action.py
deleted file mode 100644
index e9829e894..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/attach_action.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""Remote client command for attaching to a container."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Attach(AbstractActionBase):
- """Class for attaching to a running container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Attach command to parent parser."""
- parser = parent.add_parser('attach', help='attach to container')
- parser.add_argument(
- '--image',
- help='image to instantiate and attach to',
- )
- parser.add_argument(
- 'command',
- nargs='*',
- help='image to instantiate and attach to',
- )
- parser.set_defaults(class_=cls, method='attach')
-
- def __init__(self, args):
- """Construct Attach class."""
- super().__init__(args)
- if not args.image:
- raise ValueError('You must supply one image id'
- ' or name to be attached.')
-
- def attach(self):
- """Attach to instantiated image."""
- args = {
- 'detach': True,
- 'tty': True,
- }
- if self._args.command:
- args['command'] = self._args.command
-
- try:
- try:
- ident = self.client.images.pull(self._args.image)
- img = self.client.images.get(ident)
- except podman.ImageNotFound as e:
- sys.stdout.flush()
- print(
- 'Image {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- return 1
-
- ctnr = img.create(**args)
- ctnr.attach(eot=4)
-
- try:
- ctnr.start()
- print()
- except (BrokenPipeError, KeyboardInterrupt):
- print('\nContainer disconnected.')
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
diff --git a/contrib/python/pypodman/pypodman/lib/actions/commit_action.py b/contrib/python/pypodman/pypodman/lib/actions/commit_action.py
deleted file mode 100644
index c166e1aff..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/commit_action.py
+++ /dev/null
@@ -1,99 +0,0 @@
-"""Remote client command for creating image from container."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase, ChangeAction
-
-
-class Commit(AbstractActionBase):
- """Class for creating image from container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Commit command to parent parser."""
- parser = parent.add_parser(
- 'commit',
- help='create image from container',
- )
- parser.add_argument(
- '--author',
- help='Set the author for the committed image',
- )
- parser.add_argument(
- '--change',
- '-c',
- action=ChangeAction,
- )
- parser.add_argument(
- '--format',
- '-f',
- choices=('oci', 'docker'),
- default='oci',
- type=str.lower,
- help='Set the format of the image manifest and metadata.'
- ' (Ignored.)',
- )
- parser.add_argument(
- '--iidfile',
- metavar='PATH',
- help='Write the image ID to the file',
- )
- parser.add_argument(
- '--message',
- '-m',
- help='Set commit message for committed image'
- ' (Only on docker images.)',
- )
- parser.add_flag(
- '--pause',
- '-p',
- help='Pause the container when creating an image',
- )
- parser.add_flag(
- '--quiet',
- '-q',
- help='Suppress output',
- )
- parser.add_argument(
- 'container',
- nargs=1,
- help='container to use as source',
- )
- parser.add_argument(
- 'image',
- nargs=1,
- help='image name to create',
- )
- parser.set_defaults(class_=cls, method='commit')
-
- def commit(self):
- """Create image from container."""
- try:
- try:
- ctnr = self.client.containers.get(self._args.container[0])
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- return 1
- else:
- ident = ctnr.commit(
- self.opts['image'][0],
- change=self.opts.get('change', None),
- message=self.opts.get('message', None),
- pause=self.opts['pause'],
- author=self.opts.get('author', None),
- )
-
- if not self.opts['quiet']:
- print(ident)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/create_action.py b/contrib/python/pypodman/pypodman/lib/actions/create_action.py
deleted file mode 100644
index 26a312bb1..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/create_action.py
+++ /dev/null
@@ -1,55 +0,0 @@
-"""Remote client command for creating container from image."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-from ._create_args import CreateArguments
-
-
-class Create(AbstractActionBase):
- """Class for creating container from image."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Create command to parent parser."""
- parser = parent.add_parser(
- 'create', help='create container from image')
-
- CreateArguments.add_arguments(parser)
-
- parser.add_argument('image', nargs=1, help='source image id')
- parser.add_argument(
- 'command',
- nargs=parent.REMAINDER,
- help='command and args to run.',
- )
- parser.set_defaults(class_=cls, method='create')
-
- def __init__(self, args):
- """Construct Create class."""
- super().__init__(args)
-
- # image id used only on client
- del self.opts['image']
-
- def create(self):
- """Create container."""
- try:
- for ident in self._args.image:
- try:
- img = self.client.images.get(ident)
- img.container(**self.opts)
- print(ident)
- except podman.ImageNotFound as e:
- sys.stdout.flush()
- print(
- 'Image {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/export_action.py b/contrib/python/pypodman/pypodman/lib/actions/export_action.py
deleted file mode 100644
index 7ef178c4c..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/export_action.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""Remote client command for export container filesystem to tarball."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Export(AbstractActionBase):
- """Class for exporting container filesystem to tarball."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Export command to parent parser."""
- parser = parent.add_parser(
- 'export',
- help='export container to tarball',
- )
- parser.add_argument(
- '--output',
- '-o',
- metavar='PATH',
- nargs=1,
- required=True,
- help='Write to this file on host',
- )
- parser.add_argument(
- 'container',
- nargs=1,
- help='container to use as source',
- )
- parser.set_defaults(class_=cls, method='export')
-
- def export(self):
- """Create tarball from container filesystem."""
- try:
- try:
- ctnr = self.client.containers.get(self._args.container[0])
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- return 1
- else:
- ctnr.export(self._args.output[0])
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/history_action.py b/contrib/python/pypodman/pypodman/lib/actions/history_action.py
deleted file mode 100644
index 76c3ad756..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/history_action.py
+++ /dev/null
@@ -1,79 +0,0 @@
-"""Remote client for reporting image history."""
-import json
-from collections import OrderedDict
-
-import humanize
-
-import podman
-from pypodman.lib import AbstractActionBase, Report, ReportColumn
-
-
-class History(AbstractActionBase):
- """Class for reporting Image History."""
-
- @classmethod
- def subparser(cls, parent):
- """Add History command to parent parser."""
- parser = parent.add_parser('history', help='report image history')
- super().subparser(parser)
- parser.add_flag(
- '--human',
- '-H',
- help='Display sizes and dates in human readable format.')
- parser.add_argument(
- '--format',
- choices=('json', 'table'),
- help="Alter the output for a format like 'json' or 'table'."
- " (default: table)")
- parser.add_argument(
- 'image', nargs='+', help='image for history report')
- parser.set_defaults(class_=cls, method='history')
-
- def __init__(self, args):
- """Construct History class."""
- super().__init__(args)
-
- self.columns = OrderedDict({
- 'id':
- ReportColumn('id', 'ID', 12),
- 'created':
- ReportColumn('created', 'CREATED', 11),
- 'createdBy':
- ReportColumn('createdBy', 'CREATED BY', 45),
- 'size':
- ReportColumn('size', 'SIZE', 8),
- 'comment':
- ReportColumn('comment', 'COMMENT', 0)
- })
-
- def history(self):
- """Report image history."""
- rows = list()
- for ident in self._args.image:
- for details in self.client.images.get(ident).history():
- fields = dict(details._asdict())
-
- if self._args.human:
- fields.update({
- 'size':
- humanize.naturalsize(details.size),
- 'created':
- humanize.naturaldate(
- podman.datetime_parse(details.created)),
- })
- del fields['tags']
-
- rows.append(fields)
-
- if self._args.quiet:
- for row in rows:
- ident = row['id'][:12] if self._args.truncate else row['id']
- print(ident)
- elif self._args.format == 'json':
- print(json.dumps(rows, indent=2), flush=True)
- else:
- with Report(self.columns, heading=self._args.heading) as report:
- report.layout(
- rows, self.columns.keys(), truncate=self._args.truncate)
- for row in rows:
- report.row(**row)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/images_action.py b/contrib/python/pypodman/pypodman/lib/actions/images_action.py
deleted file mode 100644
index 21376eeeb..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/images_action.py
+++ /dev/null
@@ -1,86 +0,0 @@
-"""Remote client commands dealing with images."""
-import operator
-from collections import OrderedDict
-
-import humanize
-
-import podman
-from pypodman.lib import AbstractActionBase, Report, ReportColumn
-
-
-class Images(AbstractActionBase):
- """Class for Image manipulation."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Images commands to parent parser."""
- parser = parent.add_parser('images', help='list images')
- super().subparser(parser)
- parser.add_argument(
- '--sort',
- choices=['created', 'id', 'repository', 'size', 'tag'],
- default='created',
- type=str.lower,
- help=('Change sort ordered of displayed images.'
- ' (default: %(default)s)'))
-
- parser.add_flag(
- '--digests',
- help='Include digests with images.')
- parser.set_defaults(class_=cls, method='list')
-
- def __init__(self, args):
- """Construct Images class."""
- super().__init__(args)
-
- self.columns = OrderedDict({
- 'name':
- ReportColumn('name', 'REPOSITORY', 0),
- 'tag':
- ReportColumn('tag', 'TAG', 10),
- 'id':
- ReportColumn('id', 'IMAGE ID', 12),
- 'created':
- ReportColumn('created', 'CREATED', 12),
- 'size':
- ReportColumn('size', 'SIZE', 8),
- 'repoDigests':
- ReportColumn('repoDigests', 'DIGESTS', 35),
- })
-
- def list(self):
- """List images."""
- images = sorted(
- self.client.images.list(),
- key=operator.attrgetter(self._args.sort))
- if not images:
- return
-
- rows = list()
- for image in images:
- fields = dict(image)
- fields.update({
- 'created':
- humanize.naturaldate(podman.datetime_parse(image.created)),
- 'size':
- humanize.naturalsize(int(image.size)),
- 'repoDigests':
- ' '.join(image.repoDigests),
- })
-
- for r in image.repoTags:
- name, tag = r.rsplit(':', 1)
- fields.update({
- 'name': name,
- 'tag': tag,
- })
- rows.append(fields)
-
- if not self._args.digests:
- del self.columns['repoDigests']
-
- with Report(self.columns, heading=self._args.heading) as report:
- report.layout(
- rows, self.columns.keys(), truncate=self._args.truncate)
- for row in rows:
- report.row(**row)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/import_action.py b/contrib/python/pypodman/pypodman/lib/actions/import_action.py
deleted file mode 100644
index 43448144a..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/import_action.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""Remote client command to import tarball as image filesystem."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase, ChangeAction
-
-
-class Import(AbstractActionBase):
- """Class for importing tarball as image filesystem."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Import command to parent parser."""
- parser = parent.add_parser(
- 'import',
- help='import tarball as image filesystem',
- )
- parser.add_argument(
- '--change',
- '-c',
- action=ChangeAction,
- )
- parser.add_argument(
- '--message',
- '-m',
- help='Set commit message for imported image.',
- )
- parser.add_argument(
- 'source',
- metavar='PATH',
- nargs=1,
- help='tarball to use as source on remote system',
- )
- parser.add_argument(
- 'reference',
- metavar='TAG',
- nargs='*',
- help='Optional tag for image. (default: None)',
- )
- parser.set_defaults(class_=cls, method='import_')
-
- def import_(self):
- """Import tarball as image filesystem."""
- # ImportImage() validates it's parameters therefore we need to create
- # pristine dict() for keywords
- options = {}
- if 'message' in self.opts:
- options['message'] = self.opts['message']
- if 'change' in self.opts and self.opts['change']:
- options['changes'] = self.opts['change']
-
- reference = self.opts['reference'][0] if 'reference' in self.opts\
- else None
-
- try:
- ident = self.client.images.import_image(
- self.opts['source'][0],
- reference,
- **options,
- )
- print(ident)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/info_action.py b/contrib/python/pypodman/pypodman/lib/actions/info_action.py
deleted file mode 100644
index 3c854a358..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/info_action.py
+++ /dev/null
@@ -1,45 +0,0 @@
-"""Remote client command for reporting on Podman service."""
-import json
-import sys
-
-import podman
-import yaml
-from pypodman.lib import AbstractActionBase
-
-
-class Info(AbstractActionBase):
- """Class for reporting on Podman Service."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Info command to parent parser."""
- parser = parent.add_parser(
- 'info', help='report info on podman service')
- parser.add_argument(
- '--format',
- choices=('json', 'yaml'),
- help="Alter the output for a format like 'json' or 'yaml'."
- " (default: yaml)")
- parser.set_defaults(class_=cls, method='info')
-
- def info(self):
- """Report on Podman Service."""
- try:
- info = self.client.system.info()
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- else:
- if self._args.format == 'json':
- print(json.dumps(info._asdict(), indent=2), flush=True)
- else:
- print(
- yaml.dump(
- dict(info._asdict()),
- canonical=False,
- default_flow_style=False),
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/inspect_action.py b/contrib/python/pypodman/pypodman/lib/actions/inspect_action.py
deleted file mode 100644
index ca5ad2215..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/inspect_action.py
+++ /dev/null
@@ -1,89 +0,0 @@
-"""Remote client command for inspecting podman objects."""
-import json
-import logging
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Inspect(AbstractActionBase):
- """Class for inspecting podman objects."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Inspect command to parent parser."""
- parser = parent.add_parser('inspect', help='inspect objects')
- parser.add_argument(
- '--type',
- '-t',
- choices=('all', 'container', 'image'),
- default='all',
- type=str.lower,
- help='Type of object to inspect',
- )
- parser.add_flag(
- '--size',
- help='Display the total file size if the type is a container.')
- parser.add_argument(
- 'objects',
- nargs='+',
- help='objects to inspect',
- )
- parser.set_defaults(class_=cls, method='inspect')
-
- def _get_container(self, ident):
- try:
- logging.debug("Getting container %s", ident)
- ctnr = self.client.containers.get(ident)
- except podman.ContainerNotFound:
- pass
- else:
- return ctnr.inspect()
-
- def _get_image(self, ident):
- try:
- logging.debug("Getting image %s", ident)
- img = self.client.images.get(ident)
- except podman.ImageNotFound:
- pass
- else:
- return img.inspect()
-
- def inspect(self):
- """Inspect provided podman objects."""
- output = []
- try:
- for ident in self._args.objects:
- obj = None
-
- if self._args.type in ('all', 'container'):
- obj = self._get_container(ident)
- if obj is None and self._args.type in ('all', 'image'):
- obj = self._get_image(ident)
-
- if obj is None:
- if self._args.type == 'container':
- msg = 'Container "{}" not found'.format(ident)
- elif self._args.type == 'image':
- msg = 'Image "{}" not found'.format(ident)
- else:
- msg = 'Object "{}" not found'.format(ident)
- print(msg, file=sys.stderr, flush=True)
- else:
- fields = obj._asdict()
- if not self._args.size:
- try:
- del fields['sizerootfs']
- except KeyError:
- pass
- output.append(fields)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- else:
- print(json.dumps(output, indent=2))
diff --git a/contrib/python/pypodman/pypodman/lib/actions/kill_action.py b/contrib/python/pypodman/pypodman/lib/actions/kill_action.py
deleted file mode 100644
index e8fb4e74d..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/kill_action.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""Remote client command for signaling podman containers."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase, SignalAction
-
-
-class Kill(AbstractActionBase):
- """Class for sending signal to main process in container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Kill command to parent parser."""
- parser = parent.add_parser('kill', help='signal container')
- parser.add_argument(
- '--signal',
- '-s',
- action=SignalAction,
- default=9,
- help='Signal to send to the container. (default: %(default)s)')
- parser.add_argument(
- 'containers',
- nargs='+',
- help='containers to signal',
- )
- parser.set_defaults(class_=cls, method='kill')
-
- def kill(self):
- """Signal provided containers."""
- try:
- for ident in self._args.containers:
- try:
- ctnr = self.client.containers.get(ident)
- ctnr.kill(self._args.signal)
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container "{}" not found'.format(e.name),
- file=sys.stderr,
- flush=True)
- else:
- print(ident)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
diff --git a/contrib/python/pypodman/pypodman/lib/actions/logs_action.py b/contrib/python/pypodman/pypodman/lib/actions/logs_action.py
deleted file mode 100644
index 91ff7bb08..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/logs_action.py
+++ /dev/null
@@ -1,61 +0,0 @@
-"""Remote client command for retrieving container logs."""
-import argparse
-import logging
-import sys
-from collections import deque
-
-import podman
-from pypodman.lib import AbstractActionBase, PositiveIntAction
-
-
-class Logs(AbstractActionBase):
- """Class for retrieving logs from container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Logs command to parent parser."""
- parser = parent.add_parser('logs', help='retrieve logs from container')
- parser.add_argument(
- '--tail',
- metavar='LINES',
- action=PositiveIntAction,
- help='Output the specified number of LINES at the end of the logs')
- parser.add_argument(
- 'container',
- nargs=1,
- help='retrieve container logs',
- )
- parser.set_defaults(class_=cls, method='logs')
-
- def __init__(self, args):
- """Construct Logs class."""
- super().__init__(args)
-
- def logs(self):
- """Retrieve logs from containers."""
- try:
- ident = self._args.container[0]
- try:
- logging.debug('Get container "%s" logs', ident)
- ctnr = self.client.containers.get(ident)
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container "{}" not found'.format(e.name),
- file=sys.stderr,
- flush=True)
- else:
- if self._args.tail:
- logs = iter(deque(ctnr.logs(), maxlen=self._args.tail))
- else:
- logs = ctnr.logs()
-
- for line in logs:
- sys.stdout.write(line)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
diff --git a/contrib/python/pypodman/pypodman/lib/actions/mount_action.py b/contrib/python/pypodman/pypodman/lib/actions/mount_action.py
deleted file mode 100644
index 905eda6da..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/mount_action.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""Remote client command for retrieving mounts from containers."""
-import sys
-from collections import OrderedDict
-
-import podman
-from pypodman.lib import AbstractActionBase, Report, ReportColumn
-
-
-class Mount(AbstractActionBase):
- """Class for retrieving mounts from container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add mount command to parent parser."""
- parser = parent.add_parser(
- 'mount', help='retrieve mounts from containers.')
- super().subparser(parser)
- parser.add_argument(
- 'containers',
- nargs='*',
- help='containers to list ports',
- )
- parser.set_defaults(class_=cls, method='mount')
-
- def __init__(self, args):
- """Construct Mount class."""
- super().__init__(args)
-
- self.columns = OrderedDict({
- 'id':
- ReportColumn('id', 'CONTAINER ID', 14),
- 'destination':
- ReportColumn('destination', 'DESTINATION', 0)
- })
-
- def mount(self):
- """Retrieve mounts from containers."""
- try:
- ctnrs = []
- if not self._args.containers:
- ctnrs = self.client.containers.list()
- else:
- for ident in self._args.containers:
- try:
- ctnrs.append(self.client.containers.get(ident))
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container "{}" not found'.format(e.name),
- file=sys.stderr,
- flush=True)
-
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
-
- if not ctnrs:
- print(
- 'Unable to find any containers.', file=sys.stderr, flush=True)
- return 1
-
- rows = list()
- for ctnr in ctnrs:
- details = ctnr.inspect()
- rows.append({
- 'id': ctnr.id,
- 'destination': details.graphdriver['data']['mergeddir']
- })
-
- with Report(self.columns, heading=self._args.heading) as report:
- report.layout(
- rows, self.columns.keys(), truncate=self._args.truncate)
- for row in rows:
- report.row(**row)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pause_action.py b/contrib/python/pypodman/pypodman/lib/actions/pause_action.py
deleted file mode 100644
index 7dc02f7fe..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pause_action.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""Remote client command for pausing processes in containers."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Pause(AbstractActionBase):
- """Class for pausing processes in container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pause command to parent parser."""
- parser = parent.add_parser('pause', help='pause container processes')
- parser.add_argument(
- 'containers',
- nargs='+',
- help='containers to pause',
- )
- parser.set_defaults(class_=cls, method='pause')
-
- def pause(self):
- """Pause provided containers."""
- try:
- for ident in self._args.containers:
- try:
- ctnr = self.client.containers.get(ident)
- ctnr.pause()
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container "{}" not found'.format(e.name),
- file=sys.stderr,
- flush=True)
- else:
- print(ident)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/__init__.py b/contrib/python/pypodman/pypodman/lib/actions/pod/__init__.py
deleted file mode 100644
index 91c54f417..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-"""Provide subparsers for pod commands."""
-from pypodman.lib.actions.pod.create_parser import CreatePod
-from pypodman.lib.actions.pod.inspect_parser import InspectPod
-from pypodman.lib.actions.pod.kill_parser import KillPod
-from pypodman.lib.actions.pod.pause_parser import PausePod
-from pypodman.lib.actions.pod.processes_parser import ProcessesPod
-from pypodman.lib.actions.pod.remove_parser import RemovePod
-from pypodman.lib.actions.pod.start_parser import StartPod
-from pypodman.lib.actions.pod.stop_parser import StopPod
-from pypodman.lib.actions.pod.top_parser import TopPod
-from pypodman.lib.actions.pod.unpause_parser import UnpausePod
-
-__all__ = [
- 'CreatePod',
- 'InspectPod',
- 'KillPod',
- 'PausePod',
- 'ProcessesPod',
- 'RemovePod',
- 'StartPod',
- 'StopPod',
- 'TopPod',
- 'UnpausePod',
-]
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py
deleted file mode 100644
index 4e0bde777..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py
+++ /dev/null
@@ -1,76 +0,0 @@
-"""Remote client command for creating pod."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class CreatePod(AbstractActionBase):
- """Implement Create Pod command."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Create command to parent parser."""
- parser = parent.add_parser('create', help='create pod')
- super().subparser(parser)
-
- parser.add_argument(
- '--cgroup-parent',
- dest='cgroupparent',
- type=str,
- help='Path to cgroups under which the'
- ' cgroup for the pod will be created.')
- parser.add_flag(
- '--infra',
- help='Create an infra container and associate it with the pod.')
- parser.add_argument(
- '-l',
- '--label',
- dest='labels',
- action='append',
- type=str,
- help='Add metadata to a pod (e.g., --label=com.example.key=value)')
- parser.add_argument(
- '-n',
- '--name',
- dest='ident',
- type=str,
- help='Assign name to the pod')
- parser.add_argument(
- '--share',
- choices=('ipc', 'net', 'pid', 'user', 'uts'),
- help='Comma deliminated list of kernel namespaces to share')
-
- parser.set_defaults(class_=cls, method='create')
-
- # TODO: Add golang CLI arguments not included in API.
- # parser.add_argument(
- # '--infra-command',
- # default='/pause',
- # help='Command to run to start the infra container.'
- # '(default: %(default)s)')
- # parser.add_argument(
- # '--infra-image',
- # default='k8s.gcr.io/pause:3.1',
- # help='Image to create for the infra container.'
- # '(default: %(default)s)')
- # parser.add_argument(
- # '--podidfile',
- # help='Write the pod ID to given file name on remote host')
-
- def create(self):
- """Create Pod from given options."""
- config = {}
- for key in ('ident', 'cgroupparent', 'infra', 'labels', 'share'):
- config[key] = self.opts.get(key)
-
- try:
- pod = self.client.pods.create(**config)
- except podman.ErrorOccurred as ex:
- sys.stdout.flush()
- print(
- '{}'.format(ex.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- else:
- print(pod.id)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/inspect_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/inspect_parser.py
deleted file mode 100644
index 3c42d636c..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/inspect_parser.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""Remote client command for inspecting pods."""
-import json
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class InspectPod(AbstractActionBase):
- """Class for reporting on pods and their containers."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Inspect command to parent parser."""
- parser = parent.add_parser(
- 'inspect',
- help='configuration and state information about a given pod')
- parser.add_argument('pod', nargs='+', help='pod(s) to inspect')
- parser.set_defaults(class_=cls, method='inspect')
-
- def inspect(self):
- """Report on provided pods."""
- output = {}
- try:
- for ident in self._args.pod:
- try:
- pod = self.client.pods.get(ident)
- except podman.PodNotFound:
- print(
- 'Pod "{}" not found.'.format(ident),
- file=sys.stdout,
- flush=True)
- output.update(pod.inspect()._asdict())
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- else:
- print(json.dumps(output, indent=2))
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py
deleted file mode 100644
index 9b6229939..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py
+++ /dev/null
@@ -1,57 +0,0 @@
-"""Remote client command for signaling pods and their containers."""
-import signal
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase, SignalAction
-from pypodman.lib import query_model as query_pods
-
-
-class KillPod(AbstractActionBase):
- """Class for sending signal to processes in pod."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Kill command to parent parser."""
- parser = parent.add_parser('kill', help='signal containers in pod')
-
- parser.add_flag(
- '--all',
- '-a',
- help='Sends signal to all pods.')
- parser.add_argument(
- '-s',
- '--signal',
- action=SignalAction,
- default=9,
- help='Signal to send to the pod. (default: %(default)s)')
- parser.add_argument('pod', nargs='*', help='pod(s) to signal')
- parser.set_defaults(class_=cls, method='kill')
-
- def __init__(self, args):
- """Construct Pod Kill object."""
- if args.all and args.pod:
- raise ValueError('You may give a pod or use --all, but not both')
- super().__init__(args)
-
- def kill(self):
- """Signal provided pods."""
- idents = None if self._args.all else self._args.pod
- pods = query_pods(self.client.pods, idents)
-
- for pod in pods:
- try:
- pod.kill(self._args.signal)
- print(pod.id)
- except podman.PodNotFound as ex:
- print(
- 'Pod "{}" not found.'.format(ex.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as e:
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py
deleted file mode 100644
index c751314ca..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""Remote client command for pausing processes in pod."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-from pypodman.lib import query_model as query_pods
-
-
-class PausePod(AbstractActionBase):
- """Class for pausing containers in pod."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Pause command to parent parser."""
- parser = parent.add_parser('pause', help='pause containers in pod')
- parser.add_flag(
- '--all',
- '-a',
- help='Pause all pods.')
- parser.add_argument('pod', nargs='*', help='pod(s) to pause.')
- parser.set_defaults(class_=cls, method='pause')
-
- def __init__(self, args):
- """Construct Pod Pause object."""
- if args.all and args.pod:
- raise ValueError('You may give a pod or use --all, but not both')
- super().__init__(args)
-
- def pause(self):
- """Pause containers in provided Pod."""
- idents = None if self._args.all else self._args.pod
- pods = query_pods(self.client.pods, idents)
-
- for pod in pods:
- try:
- pod.pause()
- print(pod.id)
- except podman.PodNotFound as ex:
- print(
- 'Pod "{}" not found'.format(ex.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as ex:
- print(
- '{}'.format(ex.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py
deleted file mode 100644
index 855e313c7..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py
+++ /dev/null
@@ -1,94 +0,0 @@
-"""Report on pod's containers' processes."""
-import operator
-from collections import OrderedDict
-
-from pypodman.lib import AbstractActionBase, Report, ReportColumn
-
-
-class ProcessesPod(AbstractActionBase):
- """Report on Pod's processes."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Ps command to parent parser."""
- parser = parent.add_parser('ps', help='list processes of pod')
- super().subparser(parser)
-
- parser.add_flag(
- '--ctr-names',
- help='Include container name in the info field.')
- parser.add_flag(
- '--ctr-ids',
- help='Include container ID in the info field.')
- parser.add_flag(
- '--ctr-status',
- help='Include container status in the info field.')
- parser.add_argument(
- '--format',
- choices=('json'),
- help='Pretty-print containers to JSON')
- parser.add_argument(
- '--sort',
- choices=('created', 'id', 'name', 'status', 'count'),
- default='created',
- type=str.lower,
- help='Sort on given field. (default: %(default)s)')
- parser.add_argument('--filter', help='Not Implemented')
- parser.set_defaults(class_=cls, method='processes')
-
- def __init__(self, args):
- """Construct ProcessesPod class."""
- if args.sort == 'created':
- args.sort = 'createdat'
- elif args.sort == 'count':
- args.sort = 'numberofcontainers'
-
- super().__init__(args)
-
- self.columns = OrderedDict({
- 'id':
- ReportColumn('id', 'POD ID', 14),
- 'name':
- ReportColumn('name', 'NAME', 30),
- 'status':
- ReportColumn('status', 'STATUS', 8),
- 'numberofcontainers':
- ReportColumn('numberofcontainers', 'NUMBER OF CONTAINERS', 0),
- 'info':
- ReportColumn('info', 'CONTAINER INFO', 0),
- })
-
- def processes(self):
- """List pods."""
- pods = sorted(
- self.client.pods.list(), key=operator.attrgetter(self._args.sort))
- if not pods:
- return
-
- rows = list()
- for pod in pods:
- fields = dict(pod)
- if self._args.ctr_ids \
- or self._args.ctr_names \
- or self._args.ctr_status:
- keys = ('id', 'name', 'status', 'info')
- info = []
- for ctnr in pod.containersinfo:
- ctnr_info = []
- if self._args.ctr_ids:
- ctnr_info.append(ctnr['id'])
- if self._args.ctr_names:
- ctnr_info.append(ctnr['name'])
- if self._args.ctr_status:
- ctnr_info.append(ctnr['status'])
- info.append("[ {} ]".format(" ".join(ctnr_info)))
- fields.update({'info': " ".join(info)})
- else:
- keys = ('id', 'name', 'status', 'numberofcontainers')
-
- rows.append(fields)
-
- with Report(self.columns, heading=self._args.heading) as report:
- report.layout(rows, keys, truncate=self._args.truncate)
- for row in rows:
- report.row(**row)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py
deleted file mode 100644
index 289325d14..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""Remote client command for deleting pod and containers."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-from pypodman.lib import query_model as query_pods
-
-
-class RemovePod(AbstractActionBase):
- """Class for removing pod and containers from storage."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Rm command to parent parser."""
- parser = parent.add_parser('rm', help='Delete pod and container(s)')
- parser.add_flag(
- '--all',
- '-a',
- help='Remove all pods.')
- parser.add_flag(
- '--force',
- '-f',
- help='Stop and remove container(s) then delete pod.')
- parser.add_argument(
- 'pod', nargs='*', help='Pod to remove. Or, use --all')
- parser.set_defaults(class_=cls, method='remove')
-
- def __init__(self, args):
- """Construct RemovePod object."""
- if args.all and args.pod:
- raise ValueError('You may give a pod or use --all, but not both')
- super().__init__(args)
-
- def remove(self):
- """Remove pod and container(s)."""
- idents = None if self._args.all else self._args.pod
- pods = query_pods(self.client.pods, idents)
-
- for pod in pods:
- try:
- pod.remove(self._args.force)
- print(pod.id)
- except podman.PodNotFound as ex:
- print(
- 'Pod "{}" not found.'.format(ex.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as ex:
- print(
- '{}'.format(ex.reason).capitalize,
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py
deleted file mode 100644
index 53f45b6de..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py
+++ /dev/null
@@ -1,50 +0,0 @@
-"""Remote client command for restarting pod and container(s)."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-from pypodman.lib import query_model as query_pods
-
-
-class RestartPod(AbstractActionBase):
- """Class for restarting containers in Pod."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Restart command to parent parser."""
- parser = parent.add_parser('restart', help='restart containers in pod')
- parser.add_flag(
- '--all',
- '-a',
- help='Restart all pods.')
- parser.add_argument(
- 'pod', nargs='*', help='Pod to restart. Or, use --all')
- parser.set_defaults(class_=cls, method='restart')
-
- def __init__(self, args):
- """Construct RestartPod object."""
- if args.all and args.pod:
- raise ValueError('You may give a pod or use --all, not both')
- super().__init__(args)
-
- def restart(self):
- """Restart pod and container(s)."""
- idents = None if self._args.all else self._args.pod
- pods = query_pods(self.client.pods, idents)
-
- for pod in pods:
- try:
- pod.restart()
- print(pod.id)
- except podman.PodNotFound as ex:
- print(
- 'Pod "{}" not found.'.format(ex.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as ex:
- print(
- '{}'.format(ex.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py
deleted file mode 100644
index ff62b839e..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py
+++ /dev/null
@@ -1,45 +0,0 @@
-"""Remote client command for starting pod and container(s)."""
-
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-from pypodman.lib import query_model as query_pods
-
-
-class StartPod(AbstractActionBase):
- """Class for starting pod and container(s)."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Start command to parent parser."""
- parser = parent.add_parser('start', help='start pod')
- parser.add_flag(
- '--all',
- '-a',
- help='Start all pods.')
- parser.add_argument(
- 'pod', nargs='*', help='Pod to start. Or, use --all')
- parser.set_defaults(class_=cls, method='start')
-
- def __init__(self, args):
- """Construct StartPod object."""
- if args.all and args.pod:
- raise ValueError('You may give a pod or use --all, but not both')
- super().__init__(args)
-
- def start(self):
- """Start pod and container(s)."""
- idents = None if self._args.all else self._args.pod
- pods = query_pods(self.client.pods, idents)
-
- for pod in pods:
- try:
- pod.start()
- except podman.ErrorOccurred as ex:
- print(
- '{}'.format(ex.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py
deleted file mode 100644
index cbf2bf1e7..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""Remote client command for stopping pod and container(s)."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-from pypodman.lib import query_model as query_pods
-
-
-class StopPod(AbstractActionBase):
- """Class for stopping pod and container(s)."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Stop command to parent parser."""
- parser = parent.add_parser('stop', help='stop pod')
- parser.add_flag(
- '--all',
- '-a',
- help='Stop all pods.')
- parser.add_argument(
- 'pod', nargs='*', help='Pod to stop. Or, use --all')
- parser.set_defaults(class_=cls, method='stop')
-
- def __init__(self, args):
- """Contruct StopPod object."""
- if args.all and args.pod:
- raise ValueError('You may give a pod or use --all, not both')
- super().__init__(args)
-
- def stop(self):
- """Stop pod and container(s)."""
- idents = None if self._args.all else self._args.pod
- pods = query_pods(self.client.pods, idents)
-
- for pod in pods:
- try:
- pod.stop()
- except podman.ErrorOccurred as ex:
- print(
- '{}'.format(ex.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/top_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/top_parser.py
deleted file mode 100644
index f27d60f14..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/top_parser.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""Remote client command for reporting on pod and container(s)."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class TopPod(AbstractActionBase):
- """Report on containers in Pod."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Top command to parent parser."""
- parser = parent.add_parser('top', help='report on containers in pod')
- parser.add_argument('pod', nargs=1, help='Pod to report on.')
- parser.set_defaults(class_=cls, method='top')
-
- def top(self):
- """Report on pod and container(s)."""
- try:
- for ident in self._args.pod:
- pod = self.client.pods.get(ident)
- print(pod.top())
- except podman.PodNotFound as ex:
- print(
- 'Pod "{}" not found.'.format(ex.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as ex:
- print(
- '{}'.format(ex.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py
deleted file mode 100644
index 5186cf9cc..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py
+++ /dev/null
@@ -1,50 +0,0 @@
-"""Remote client command for unpausing processes in pod."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-from pypodman.lib import query_model as query_pods
-
-
-class UnpausePod(AbstractActionBase):
- """Class for unpausing containers in pod."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Unpause command to parent parser."""
- parser = parent.add_parser('unpause', help='unpause pod')
- parser.add_flag(
- '--all',
- '-a',
- help='Unpause all pods.')
- parser.add_argument(
- 'pod', nargs='*', help='Pod to unpause. Or, use --all')
- parser.set_defaults(class_=cls, method='unpause')
-
- def __init__(self, args):
- """Construct Pod Unpause class."""
- if args.all and args.pod:
- raise ValueError('You may give a pod or use --all, but not both')
- super().__init__(args)
-
- def unpause(self):
- """Unpause containers in provided Pod."""
- idents = None if self._args.all else self._args.pod
- pods = query_pods(self.client.pods, idents)
-
- for pod in pods:
- try:
- pod.unpause()
- print(pod.id)
- except podman.PodNotFound as ex:
- print(
- 'Pod "{}" not found'.format(ex.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as ex:
- print(
- '{}'.format(ex.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod_action.py b/contrib/python/pypodman/pypodman/lib/actions/pod_action.py
deleted file mode 100644
index 4b8997a05..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pod_action.py
+++ /dev/null
@@ -1,36 +0,0 @@
-"""Remote client command for pod subcommands."""
-import inspect
-import logging
-import sys
-
-from pypodman.lib import AbstractActionBase
-
-# pylint: disable=wildcard-import
-# pylint: disable=unused-wildcard-import
-from .pod import *
-
-
-class Pod(AbstractActionBase):
- """Class for creating a pod."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pod Create command to parent parser."""
- pod_parser = parent.add_parser(
- 'pod',
- help='pod commands.'
- ' For subcommands, see: %(prog)s pod --help')
- subparser = pod_parser.add_subparsers()
-
- # pull in plugin(s) code for each subcommand
- for name, obj in inspect.getmembers(
- sys.modules['pypodman.lib.actions.pod'],
- predicate=inspect.isclass):
- if hasattr(obj, 'subparser'):
- try:
- obj.subparser(subparser)
- except NameError as e:
- logging.critical(e)
- logging.warning(
- 'See subparser configuration for Class "%s"', name)
- sys.exit(3)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/port_action.py b/contrib/python/pypodman/pypodman/lib/actions/port_action.py
deleted file mode 100644
index 6913f3813..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/port_action.py
+++ /dev/null
@@ -1,61 +0,0 @@
-"""Remote client command for retrieving ports from containers."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Port(AbstractActionBase):
- """Class for retrieving ports from container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Port command to parent parser."""
- parser = parent.add_parser(
- 'port', help='retrieve ports from containers')
- parser.add_flag(
- '--all',
- '-a',
- help='List all known port mappings for running containers')
- parser.add_argument(
- 'containers',
- nargs='*',
- help='containers to list ports',
- )
- parser.set_defaults(class_=cls, method='port')
-
- def __init__(self, args):
- """Construct Port class."""
- if not args.all and not args.containers:
- raise ValueError('You must supply at least one'
- ' container id or name, or --all.')
- super().__init__(args)
-
- def port(self):
- """Retrieve ports from containers."""
- try:
- ctnrs = []
- if self._args.all:
- ctnrs = self.client.containers.list()
- else:
- for ident in self._args.containers:
- try:
- ctnrs.append(self.client.containers.get(ident))
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container "{}" not found'.format(e.name),
- file=sys.stderr,
- flush=True)
-
- for ctnr in ctnrs:
- print("{}\n{}".format(ctnr.id, ctnr.ports))
-
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/ps_action.py b/contrib/python/pypodman/pypodman/lib/actions/ps_action.py
deleted file mode 100644
index 62ceb2e67..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/ps_action.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""Remote client commands dealing with containers."""
-import operator
-from collections import OrderedDict
-
-import humanize
-
-import podman
-from pypodman.lib import AbstractActionBase, Report, ReportColumn
-
-
-class Ps(AbstractActionBase):
- """Class for Container manipulation."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Images command to parent parser."""
- parser = parent.add_parser('ps', help='list containers')
- super().subparser(parser)
-
- parser.add_argument(
- '--sort',
- choices=('createdat', 'id', 'image', 'names', 'runningfor', 'size',
- 'status'),
- default='createdat',
- type=str.lower,
- help=('Change sort ordered of displayed containers.'
- ' (default: %(default)s)'))
- parser.set_defaults(class_=cls, method='list')
-
- def __init__(self, args):
- """Construct Ps class."""
- super().__init__(args)
-
- self.columns = OrderedDict({
- 'id':
- ReportColumn('id', 'CONTAINER ID', 12),
- 'image':
- ReportColumn('image', 'IMAGE', 31),
- 'command':
- ReportColumn('column', 'COMMAND', 20),
- 'createdat':
- ReportColumn('createdat', 'CREATED', 12),
- 'status':
- ReportColumn('status', 'STATUS', 10),
- 'ports':
- ReportColumn('ports', 'PORTS', 0),
- 'names':
- ReportColumn('names', 'NAMES', 18)
- })
-
- def list(self):
- """List containers."""
- if self._args.all:
- ictnrs = self.client.containers.list()
- else:
- ictnrs = filter(
- lambda c: podman.FoldedString(c['status']) == 'running',
- self.client.containers.list())
-
- # TODO: Verify sorting on dates and size
- ctnrs = sorted(ictnrs, key=operator.attrgetter(self._args.sort))
- if not ctnrs:
- return
-
- rows = list()
- for ctnr in ctnrs:
- fields = dict(ctnr)
- fields.update({
- 'command':
- ' '.join(ctnr.command),
- 'createdat':
- humanize.naturaldate(podman.datetime_parse(ctnr.createdat)),
- })
- rows.append(fields)
-
- with Report(self.columns, heading=self._args.heading) as report:
- report.layout(
- rows, self.columns.keys(), truncate=self._args.truncate)
- for row in rows:
- report.row(**row)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pull_action.py b/contrib/python/pypodman/pypodman/lib/actions/pull_action.py
deleted file mode 100644
index d8fbfc1f0..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/pull_action.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""Remote client command for pulling images."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Pull(AbstractActionBase):
- """Class for retrieving images from repository."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Pull command to parent parser."""
- parser = parent.add_parser(
- 'pull',
- help='retrieve image from repository',
- )
- parser.add_argument(
- 'targets',
- nargs='+',
- help='image id(s) to retrieve.',
- )
- parser.set_defaults(class_=cls, method='pull')
-
- def __init__(self, args):
- """Construct Pull class."""
- super().__init__(args)
-
- def pull(self):
- """Retrieve image."""
- for ident in self._args.targets:
- try:
- self.client.images.pull(ident)
- print(ident)
- except podman.ImageNotFound as e:
- sys.stdout.flush()
- print(
- 'Image {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/push_action.py b/contrib/python/pypodman/pypodman/lib/actions/push_action.py
deleted file mode 100644
index 8e86ca335..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/push_action.py
+++ /dev/null
@@ -1,50 +0,0 @@
-"""Remote client command for pushing image elsewhere."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Push(AbstractActionBase):
- """Class for pushing images to repository."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Push command to parent parser."""
- parser = parent.add_parser(
- 'push',
- help='push image elsewhere',
- )
- parser.add_flag(
- '--tlsverify',
- help='Require HTTPS and verify certificates when'
- ' contacting registries.')
- parser.add_argument(
- 'image', nargs=1, help='name or id of image to push')
- parser.add_argument(
- 'tag',
- nargs=1,
- help='destination image id',
- )
- parser.set_defaults(class_=cls, method='push')
-
- def pull(self):
- """Store image elsewhere."""
- try:
- try:
- img = self.client.images.get(self._args.image[0])
- except podman.ImageNotFound as e:
- sys.stdout.flush()
- print(
- 'Image {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- else:
- img.push(self._args.tag[0], tlsverify=self._args.tlsverify)
- print(self._args.image[0])
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/restart_action.py b/contrib/python/pypodman/pypodman/lib/actions/restart_action.py
deleted file mode 100644
index 415594920..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/restart_action.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""Remote client command for restarting containers."""
-import logging
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase, PositiveIntAction
-
-
-class Restart(AbstractActionBase):
- """Class for Restarting containers."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Restart command to parent parser."""
- parser = parent.add_parser('restart', help='restart container(s)')
- parser.add_argument(
- '--timeout',
- action=PositiveIntAction,
- default=10,
- help='Timeout to wait before forcibly stopping the container'
- ' (default: %(default)s seconds)')
- parser.add_argument(
- 'targets', nargs='+', help='container id(s) to restart')
- parser.set_defaults(class_=cls, method='restart')
-
- def restart(self):
- """Restart container(s)."""
- try:
- for ident in self._args.targets:
- try:
- ctnr = self.client.containers.get(ident)
- logging.debug('Restarting Container %s', ctnr.id)
- ctnr.restart(timeout=self._args.timeout)
- print(ident)
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/rm_action.py b/contrib/python/pypodman/pypodman/lib/actions/rm_action.py
deleted file mode 100644
index 99ff6c460..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/rm_action.py
+++ /dev/null
@@ -1,41 +0,0 @@
-"""Remote client command for deleting containers."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Rm(AbstractActionBase):
- """Class for removing containers from storage."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Rm command to parent parser."""
- parser = parent.add_parser('rm', help='delete container(s)')
- parser.add_flag(
- '--force',
- '-f',
- help='force delete of running container(s).')
- parser.add_argument(
- 'targets', nargs='+', help='container id(s) to delete')
- parser.set_defaults(class_=cls, method='remove')
-
- def remove(self):
- """Remove container(s)."""
- for ident in self._args.targets:
- try:
- ctnr = self.client.containers.get(ident)
- ctnr.remove(self._args.force)
- print(ident)
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/rmi_action.py b/contrib/python/pypodman/pypodman/lib/actions/rmi_action.py
deleted file mode 100644
index 7c3d0bd79..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/rmi_action.py
+++ /dev/null
@@ -1,40 +0,0 @@
-"""Remote client command for deleting images."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Rmi(AbstractActionBase):
- """Class for removing images from storage."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Rmi command to parent parser."""
- parser = parent.add_parser('rmi', help='delete image(s)')
- parser.add_flag(
- '--force',
- '-f',
- help='force delete of image(s) and associated containers.')
- parser.add_argument('targets', nargs='+', help='image id(s) to delete')
- parser.set_defaults(class_=cls, method='remove')
-
- def remove(self):
- """Remove image(s)."""
- for ident in self._args.targets:
- try:
- img = self.client.images.get(ident)
- img.remove(self._args.force)
- print(ident)
- except podman.ImageNotFound as e:
- sys.stdout.flush()
- print(
- 'Image {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/run_action.py b/contrib/python/pypodman/pypodman/lib/actions/run_action.py
deleted file mode 100644
index 6a6b3cb2c..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/run_action.py
+++ /dev/null
@@ -1,73 +0,0 @@
-"""Remote client command for run a command in a new container."""
-import logging
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-from ._create_args import CreateArguments
-
-
-class Run(AbstractActionBase):
- """Class for running a command in a container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Run command to parent parser."""
- parser = parent.add_parser('run', help='Run container from image')
-
- CreateArguments.add_arguments(parser)
-
- parser.add_argument('image', nargs=1, help='source image id.')
- parser.add_argument(
- 'command',
- nargs=parent.REMAINDER,
- help='command and args to run.',
- )
- parser.set_defaults(class_=cls, method='run')
-
- def __init__(self, args):
- """Construct Run class."""
- super().__init__(args)
- if args.detach and args.rm:
- raise ValueError('Incompatible options: --detach and --rm')
-
- # image id used only on client
- del self.opts['image']
-
- def run(self):
- """Run container."""
- for ident in self._args.image:
- try:
- try:
- img = self.client.images.get(ident)
- ctnr = img.container(**self.opts)
- except podman.ImageNotFound as e:
- sys.stdout.flush()
- print(
- 'Image {} not found.'.format(e.name),
- file=sys.stderr,
- flush=True)
- continue
- else:
- logging.debug('New container created "{}"'.format(ctnr.id))
-
- if self._args.detach:
- ctnr.start()
- print(ctnr.id)
- else:
- ctnr.attach(eot=4)
- ctnr.start()
- print(ctnr.id)
-
- if self._args.rm:
- ctnr.remove(force=True)
- except (BrokenPipeError, KeyboardInterrupt):
- print('\nContainer "{}" disconnected.'.format(ctnr.id))
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- 'Run for container "{}" failed: {} {}'.format(
- ctnr.id, repr(e), e.reason.capitalize()),
- file=sys.stderr,
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/search_action.py b/contrib/python/pypodman/pypodman/lib/actions/search_action.py
deleted file mode 100644
index b7b8b465d..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/search_action.py
+++ /dev/null
@@ -1,160 +0,0 @@
-"""Remote client command for searching registries for an image."""
-import argparse
-import sys
-from collections import OrderedDict
-
-import podman
-from pypodman.lib import (AbstractActionBase, PositiveIntAction, Report,
- ReportColumn)
-
-
-class FilterAction(argparse.Action):
- """Parse filter argument components."""
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar='FILTER'):
- """Create FilterAction object."""
- help = (help or '') + (' (format: stars=##'
- ' or is-automated=[True|False]'
- ' or is-official=[True|False])')
- super().__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- """
- Convert and Validate input.
-
- Note: side effects
- 1) self.dest value is set to subargument dest
- 2) new attribute self.dest + '_value' is created with 2nd value.
- """
- opt, val = values.split('=', 1)
- if opt == 'stars':
- msg = ('{} option "stars" requires'
- ' a positive integer').format(self.dest)
- try:
- val = int(val)
- except ValueError:
- parser.error(msg)
-
- if val < 0:
- parser.error(msg)
- elif opt == 'is-automated':
- if val.capitalize() in ('True', 'False'):
- val = bool(val)
- else:
- msg = ('{} option "is-automated"'
- ' must be True or False.'.format(self.dest))
- parser.error(msg)
- elif opt == 'is-official':
- if val.capitalize() in ('True', 'False'):
- val = bool(val)
- else:
- msg = ('{} option "is-official"'
- ' must be True or False.'.format(self.dest))
- parser.error(msg)
- else:
- msg = ('{} only supports one of the following options:\n'
- ' stars, is-automated, or is-official').format(self.dest)
- parser.error(msg)
- setattr(namespace, self.dest, opt)
- setattr(namespace, self.dest + '_value', val)
-
-
-class Search(AbstractActionBase):
- """Class for searching registries for an image."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Search command to parent parser."""
- parser = parent.add_parser('search', help='search for images')
- super().subparser(parser)
- parser.add_argument(
- '--filter',
- '-f',
- action=FilterAction,
- help='Filter output based on conditions provided.')
- parser.add_argument(
- '--limit',
- action=PositiveIntAction,
- default=25,
- help='Limit the number of results.'
- ' (default: %(default)s)')
- parser.add_argument('term', nargs=1, help='search term for image')
- parser.set_defaults(class_=cls, method='search')
-
- def __init__(self, args):
- """Construct Search class."""
- super().__init__(args)
-
- self.columns = OrderedDict({
- 'name':
- ReportColumn('name', 'NAME', 44),
- 'description':
- ReportColumn('description', 'DESCRIPTION', 44),
- 'star_count':
- ReportColumn('star_count', 'STARS', 5),
- 'is_official':
- ReportColumn('is_official', 'OFFICIAL', 8),
- 'is_automated':
- ReportColumn('is_automated', 'AUTOMATED', 9),
- })
-
- def search(self):
- """Search registries for image."""
- try:
- rows = list()
- for entry in self.client.images.search(
- self._args.term[0], limit=self._args.limit):
-
- if self._args.filter == 'is-official':
- if self._args.filter_value != entry.is_official:
- continue
- elif self._args.filter == 'is-automated':
- if self._args.filter_value != entry.is_automated:
- continue
- elif self._args.filter == 'stars':
- if self._args.filter_value > entry.star_count:
- continue
-
- fields = dict(entry._asdict())
-
- status = '[OK]' if entry.is_official else ''
- fields['is_official'] = status
-
- status = '[OK]' if entry.is_automated else ''
- fields['is_automated'] = status
-
- if self._args.truncate:
- fields.update({'name': entry.name[-44:]})
- rows.append(fields)
-
- with Report(self.columns, heading=self._args.heading) as report:
- report.layout(
- rows, self.columns.keys(), truncate=self._args.truncate)
- for row in rows:
- report.row(**row)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/start_action.py b/contrib/python/pypodman/pypodman/lib/actions/start_action.py
deleted file mode 100644
index 5f88731dc..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/start_action.py
+++ /dev/null
@@ -1,71 +0,0 @@
-"""Remote client command for starting containers."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Start(AbstractActionBase):
- """Class for starting container."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Start command to parent parser."""
- parser = parent.add_parser('start', help='start container')
- parser.add_flag(
- '--attach',
- '-a',
- help="Attach container's STDOUT and STDERR.")
- parser.add_argument(
- '--detach-keys',
- metavar='KEY(s)',
- default=4,
- help='Override the key sequence for detaching a container.'
- ' (format: a single character [a-Z] or ctrl-<value> where'
- ' <value> is one of: a-z, @, ^, [, , or _) (default: ^D)')
- parser.add_flag(
- '--interactive',
- '-i',
- help="Attach container's STDIN.")
- # TODO: Implement sig-proxy
- parser.add_flag(
- '--sig-proxy',
- help="Proxy received signals to the process."
- )
- parser.add_argument(
- 'containers',
- nargs='+',
- help='containers to start',
- )
- parser.set_defaults(class_=cls, method='start')
-
- def start(self):
- """Start provided containers."""
- stdin = sys.stdin if self.opts['interactive'] else None
- stdout = sys.stdout if self.opts['attach'] else None
-
- try:
- for ident in self._args.containers:
- try:
- ctnr = self.client.containers.get(ident)
- ctnr.attach(
- eot=self.opts['detach_keys'],
- stdin=stdin,
- stdout=stdout)
- ctnr.start()
- except podman.ContainerNotFound as e:
- sys.stdout.flush()
- print(
- 'Container "{}" not found'.format(e.name),
- file=sys.stderr,
- flush=True)
- else:
- print(ident)
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/version_action.py b/contrib/python/pypodman/pypodman/lib/actions/version_action.py
deleted file mode 100644
index 29a0cabe4..000000000
--- a/contrib/python/pypodman/pypodman/lib/actions/version_action.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""Remote client command for reporting on Podman service."""
-import sys
-
-import podman
-from pypodman.lib import AbstractActionBase
-
-
-class Version(AbstractActionBase):
- """Class for reporting on Podman Service."""
-
- @classmethod
- def subparser(cls, parent):
- """Add Version command to parent parser."""
- parser = parent.add_parser(
- 'version', help='report version on podman service')
- parser.set_defaults(class_=cls, method='version')
-
- def version(self):
- """Report on Podman Service."""
- try:
- info = self.client.system.info()
- except podman.ErrorOccurred as e:
- sys.stdout.flush()
- print(
- '{}'.format(e.reason).capitalize(),
- file=sys.stderr,
- flush=True)
- return 1
- else:
- version = info._asdict()['podman']
- host = info._asdict()['host']
- print("Version {}".format(version['podman_version']))
- print("Go Version {}".format(version['go_version']))
- print("Git Commit {}".format(version['git_commit']))
- print("OS/Arch {}/{}".format(host["os"], host["arch"]))
diff --git a/contrib/python/pypodman/pypodman/lib/parser_actions.py b/contrib/python/pypodman/pypodman/lib/parser_actions.py
deleted file mode 100644
index 3ff12cab8..000000000
--- a/contrib/python/pypodman/pypodman/lib/parser_actions.py
+++ /dev/null
@@ -1,247 +0,0 @@
-"""
-Supplimental argparse.Action converters and validaters.
-
-The constructors are very verbose but remain for IDE support.
-"""
-import argparse
-import copy
-import os
-import signal
-
-# API defined by argparse.Action therefore shut up pylint
-# pragma pylint: disable=redefined-builtin
-# pragma pylint: disable=too-few-public-methods
-# pragma pylint: disable=too-many-arguments
-
-
-class ChangeAction(argparse.Action):
- """Convert and validate change argument."""
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar='OPT=VALUE'):
- """Create ChangeAction object."""
- help = (help or '') + ('Apply change(s) to the new image.'
- ' May be given multiple times.')
- if default is None:
- default = []
-
- super().__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- """Convert and Validate input."""
- items = getattr(namespace, self.dest, None) or []
- items = copy.copy(items)
-
- choices = ('CMD', 'ENTRYPOINT', 'ENV', 'EXPOSE', 'LABEL', 'ONBUILD',
- 'STOPSIGNAL', 'USER', 'VOLUME', 'WORKDIR')
-
- opt, _ = values.split('=', 1)
- if opt not in choices:
- parser.error('Option "{}" is not supported by argument "{}",'
- ' valid options are: {}'.format(
- opt, option_string, ', '.join(choices)))
- items.append(values)
- setattr(namespace, self.dest, items)
-
-
-class SignalAction(argparse.Action):
- """Validate input as a signal."""
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=str,
- choices=None,
- required=False,
- help='The signal to send.'
- ' It may be given as a name or a number.',
- metavar='SIGNAL'):
- """Create SignalAction object."""
- super().__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- if hasattr(signal, "Signals"):
-
- def _signal_number(signame):
- cooked = 'SIG{}'.format(signame)
- try:
- return signal.Signals[cooked].value
- except ValueError:
- pass
- else:
-
- def _signal_number(signame):
- cooked = 'SIG{}'.format(signame)
- for n, v in sorted(signal.__dict__.items()):
- if n != cooked:
- continue
- if n.startswith("SIG") and not n.startswith("SIG_"):
- return v
-
- self._signal_number = _signal_number
-
- def __call__(self, parser, namespace, values, option_string=None):
- """Validate input is a signal for platform."""
- if values.isdigit():
- signum = int(values)
- if signal.SIGRTMIN <= signum >= signal.SIGRTMAX:
- raise ValueError('"{}" is not a valid signal. {}-{}'.format(
- values, signal.SIGRTMIN, signal.SIGRTMAX))
- else:
- signum = self._signal_number(values)
- if signum is None:
- parser.error(
- '"{}" is not a valid signal,'
- ' see your platform documentation.'.format(values))
- setattr(namespace, self.dest, signum)
-
-
-class UnitAction(argparse.Action):
- """Validate number given is positive integer, with optional suffix."""
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar='UNIT'):
- """Create UnitAction object."""
- help = (help or metavar or dest)\
- + ' (format: <number>[<unit>], where unit = b, k, m or g)'
- super().__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- """Validate input as a UNIT."""
- try:
- val = int(values)
- except ValueError:
- if not values[:-1].isdigit():
- msg = ('{} must be a positive integer,'
- ' with optional suffix').format(option_string)
- parser.error(msg)
- if not values[-1] in ('b', 'k', 'm', 'g'):
- msg = '{} only supports suffices of: b, k, m, g'.format(
- option_string)
- parser.error(msg)
- else:
- if val <= 0:
- msg = '{} must be a positive integer'.format(option_string)
- parser.error(msg)
-
- setattr(namespace, self.dest, values)
-
-
-class PositiveIntAction(argparse.Action):
- """Validate number given is positive integer."""
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=int,
- choices=None,
- required=False,
- help='Must be a positive integer.',
- metavar=None):
- """Create PositiveIntAction object."""
- super().__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- """Validate input."""
- if values > 0:
- setattr(namespace, self.dest, values)
- return
-
- msg = '{} must be a positive integer'.format(option_string)
- parser.error(msg)
-
-
-class PathAction(argparse.Action):
- """Expand user- and relative-paths."""
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar='PATH'):
- """Create PathAction object."""
- super().__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- """Resolve full path value on local filesystem."""
- setattr(namespace, self.dest,
- os.path.abspath(os.path.expanduser(values)))
diff --git a/contrib/python/pypodman/pypodman/lib/podman_parser.py b/contrib/python/pypodman/pypodman/lib/podman_parser.py
deleted file mode 100644
index 913546a91..000000000
--- a/contrib/python/pypodman/pypodman/lib/podman_parser.py
+++ /dev/null
@@ -1,255 +0,0 @@
-"""Parse configuration while building subcommands."""
-import argparse
-import getpass
-import inspect
-import logging
-import os
-import shutil
-import sys
-from contextlib import suppress
-from pathlib import Path
-
-import pkg_resources
-import pytoml
-
-from .parser_actions import PathAction, PositiveIntAction
-
-# TODO: setup.py and obtain __version__ from rpm.spec
-try:
- __version__ = pkg_resources.get_distribution('pypodman').version
-except Exception: # pylint: disable=broad-except
- __version__ = '0.0.0'
-
-
-class HelpFormatter(argparse.RawDescriptionHelpFormatter):
- """Set help width to screen size."""
-
- def __init__(self, *args, **kwargs):
- """Construct HelpFormatter using screen width."""
- if 'width' not in kwargs:
- try:
- size = shutil.get_terminal_size()
- kwargs['width'] = size.columns
- except Exception: # pylint: disable=broad-except
- kwargs['width'] = 80
-
- super().__init__(*args, **kwargs)
-
-
-class PodmanArgumentParser(argparse.ArgumentParser):
- """Default remote podman configuration."""
-
- def __init__(self, **kwargs):
- """Construct the parser."""
- kwargs['add_help'] = True
- kwargs['description'] = ('Portable and simple management'
- ' tool for containers and images')
- kwargs['formatter_class'] = HelpFormatter
-
- super().__init__(**kwargs)
-
- def add_flag(self, *args, **kwargs):
- """Add flag to parser."""
- flags = [a for a in args if a[0] in self.prefix_chars]
- dest = flags[0].lstrip(self.prefix_chars)
- no_flag = '{0}{0}no-{1}'.format(self.prefix_chars, dest)
-
- group = self.add_mutually_exclusive_group(required=False)
- group.add_argument(*flags, action='store_true', dest=dest, **kwargs)
- group.add_argument(no_flag, action='store_false', dest=dest, **kwargs)
- default = kwargs.get('default', False)
- self.set_defaults(**{dest: default})
-
- def initialize_parser(self):
- """Initialize parser without causing recursion meltdown."""
- self.add_argument(
- '--version',
- action='version',
- version='%(prog)s v. ' + __version__)
- self.add_argument(
- '--log-level',
- choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
- default='WARNING',
- type=str.upper,
- help='set logging level for events. (default: %(default)s)',
- )
- self.add_argument(
- '--run-dir',
- metavar='DIRECTORY',
- help=('directory to place local socket bindings.'
- ' (default: XDG_RUNTIME_DIR/pypodman)'))
- self.add_argument(
- '--username',
- '-l',
- help='Authenicating user on remote host. (default: {})'.format(
- getpass.getuser()))
- self.add_argument(
- '--host', help='name of remote host. (default: None)')
- self.add_argument(
- '--port',
- '-p',
- action=PositiveIntAction,
- help='port for ssh tunnel to remote host. (default: 22)')
- self.add_argument(
- '--remote-socket-path',
- metavar='PATH',
- help=('path of podman socket on remote host'
- ' (default: /run/podman/io.podman)'))
- self.add_argument(
- '--identity-file',
- '-i',
- action=PathAction,
- help='path to ssh identity file. (default: ~user/.ssh/id_dsa)')
- self.add_argument(
- '--config-home',
- metavar='DIRECTORY',
- action=PathAction,
- help=('home of configuration "pypodman.conf".'
- ' (default: XDG_CONFIG_HOME/pypodman)'))
-
- actions_parser = self.add_subparsers(
- dest='subparser_name', help='commands')
- # For create/exec/run: don't process options intended for subcommand
- actions_parser.REMAINDER = argparse.REMAINDER
-
- # import buried here to prevent import loops
- import pypodman.lib.actions # pylint: disable=cyclic-import
- assert pypodman.lib.actions
-
- # pull in plugin(s) code for each subcommand
- for name, obj in inspect.getmembers(
- sys.modules['pypodman.lib.actions'],
- predicate=inspect.isclass):
- if hasattr(obj, 'subparser'):
- try:
- obj.subparser(actions_parser)
- except NameError as e:
- logging.critical(e)
- logging.warning(
- 'See subparser configuration for Class "%s"', name)
- sys.exit(3)
-
- def parse_args(self, args=None, namespace=None):
- """Parse command line arguments, backed by env var and config_file."""
- self.initialize_parser()
- cooked = super().parse_args(args, namespace)
- return self.resolve_configuration(cooked)
-
- def resolve_configuration(self, args):
- """Find and fill in any arguments not passed on command line."""
- args.xdg_runtime_dir = os.environ.get('XDG_RUNTIME_DIR', '/tmp')
- args.xdg_config_home = os.environ.get('XDG_CONFIG_HOME',
- os.path.expanduser('~/.config'))
- args.xdg_config_dirs = os.environ.get('XDG_CONFIG_DIRS', '/etc/xdg')
-
- # Configuration file(s) are optional,
- # required arguments may be provided elsewhere
- config = {'default': {}}
- dirs = args.xdg_config_dirs.split(':')
- dirs.extend((args.xdg_config_home, args.config_home))
- for dir_ in dirs:
- if dir_ is None:
- continue
- with suppress(OSError):
- cnf = Path(dir_, 'pypodman', 'pypodman.conf')
- with cnf.open() as stream:
- config.update(pytoml.load(stream))
-
- def reqattr(name, value):
- """Raise an error if value is unset."""
- if value:
- setattr(args, name, value)
- return value
- return self.error(
- 'Required argument "{}" is not configured.'.format(name))
-
- reqattr(
- 'run_dir',
- getattr(args, 'run_dir')
- or os.environ.get('PODMAN_RUN_DIR')
- or config['default'].get('run_dir')
- or str(Path(args.xdg_runtime_dir, 'pypodman'))
- ) # yapf: disable
-
- setattr(
- args,
- 'host',
- getattr(args, 'host')
- or os.environ.get('PODMAN_HOST')
- or config['default'].get('host')
- ) # yapf:disable
-
- reqattr(
- 'username',
- getattr(args, 'username')
- or os.environ.get('PODMAN_USER')
- or config['default'].get('username')
- or os.environ.get('USER')
- or os.environ.get('LOGNAME')
- or getpass.getuser()
- ) # yapf:disable
-
- reqattr(
- 'port',
- getattr(args, 'port')
- or os.environ.get('PODMAN_PORT')
- or config['default'].get('port', None)
- or 22
- ) # yapf:disable
-
- reqattr(
- 'remote_socket_path',
- getattr(args, 'remote_socket_path')
- or os.environ.get('PODMAN_REMOTE_SOCKET_PATH')
- or config['default'].get('remote_socket_path')
- or '/run/podman/io.podman'
- ) # yapf:disable
-
- reqattr(
- 'log_level',
- getattr(args, 'log_level')
- or os.environ.get('PODMAN_LOG_LEVEL')
- or config['default'].get('log_level')
- or logging.WARNING
- ) # yapf:disable
-
- setattr(
- args,
- 'identity_file',
- getattr(args, 'identity_file')
- or os.environ.get('PODMAN_IDENTITY_FILE')
- or config['default'].get('identity_file')
- or os.path.expanduser('~{}/.ssh/id_dsa'.format(args.username))
- ) # yapf:disable
-
- if not os.path.isfile(args.identity_file):
- args.identity_file = None
-
- if args.host:
- args.local_socket_path = str(Path(args.run_dir, 'podman.socket'))
- else:
- args.local_socket_path = args.remote_socket_path
-
- args.local_uri = 'unix:{}'.format(args.local_socket_path)
-
- if args.host:
- components = ['ssh://', args.username, '@', args.host]
- if args.port:
- components.extend((':', str(args.port)))
- components.append(args.remote_socket_path)
-
- args.remote_uri = ''.join(components)
- return args
-
- def exit(self, status=0, message=None):
- """Capture message and route to logger."""
- if message:
- log = logging.info if status == 0 else logging.error
- log(message)
- super().exit(status)
-
- def error(self, message):
- """Capture message and route to logger."""
- logging.error('%s: %s', self.prog, message)
- logging.error("Try '%s --help' for more information.", self.prog)
- super().exit(2)
diff --git a/contrib/python/pypodman/pypodman/lib/report.py b/contrib/python/pypodman/pypodman/lib/report.py
deleted file mode 100644
index b689390fd..000000000
--- a/contrib/python/pypodman/pypodman/lib/report.py
+++ /dev/null
@@ -1,87 +0,0 @@
-"""Report Manager."""
-import string
-import sys
-from collections import namedtuple
-
-
-class ReportFormatter(string.Formatter):
- """Custom formatter to default missing keys to '<none>'."""
-
- def get_value(self, key, args, kwargs):
- """Map missing key to value '<none>'."""
- try:
- if isinstance(key, int):
- return args[key]
- else:
- return kwargs[key]
- except KeyError:
- return '<none>'
-
-
-class ReportColumn(namedtuple('ReportColumn', 'key display width default')):
- """Hold attributes of output column."""
-
- __slots__ = ()
-
- def __new__(cls, key, display, width, default=None):
- """Add defaults for attributes."""
- return super(ReportColumn, cls).__new__(cls, key, display, width,
- default)
-
-
-class Report():
- """Report Manager."""
-
- def __init__(self, columns, heading=True, epilog=None, file=sys.stdout):
- """Construct Report.
-
- columns is a mapping for named fields to column headings.
- headers True prints headers on table.
- epilog will be printed when the report context is closed.
- """
- self._columns = columns
- self._file = file
- self._format_string = None
- self._formatter = ReportFormatter()
- self._heading = heading
- self.epilog = epilog
-
- def row(self, **fields):
- """Print row for report."""
- if self._heading:
- hdrs = {k: v.display for (k, v) in self._columns.items()}
- print(
- self._formatter.format(self._format_string, **hdrs),
- flush=True,
- file=self._file,
- )
- self._heading = False
-
- fields = {k: str(v) for k, v in fields.items()}
- print(self._formatter.format(self._format_string, **fields))
-
- def __enter__(self):
- """Return `self` upon entering the runtime context."""
- return self
-
- def __exit__(self, exc_type, exc_value, traceback):
- """Leave Report context and print epilog if provided."""
- if self.epilog:
- print(self.epilog, flush=True, file=self._file)
-
- def layout(self, iterable, keys, truncate=True):
- """Use data and headings build format for table to fit."""
- fmt = []
-
- for key in keys:
- slice_ = [str(i.get(key, '')) for i in iterable]
- data_len = len(max(slice_, key=len))
-
- info = self._columns.get(key,
- ReportColumn(key, key.upper(), data_len))
- display_len = max(data_len, len(info.display))
- if truncate and info.width != 0:
- display_len = info.width
-
- fmt.append('{{{0}:{1}.{1}}}'.format(key, display_len))
- self._format_string = ' '.join(fmt)
diff --git a/contrib/python/pypodman/pypodman/main.py b/contrib/python/pypodman/pypodman/main.py
deleted file mode 100755
index e512dc483..000000000
--- a/contrib/python/pypodman/pypodman/main.py
+++ /dev/null
@@ -1,81 +0,0 @@
-"""Remote podman client."""
-import logging
-import os
-import sys
-from subprocess import CalledProcessError
-
-from pypodman.lib import PodmanArgumentParser
-
-
-def main():
- """Entry point."""
- # Setup logging so we use stderr and can change logging level later
- # Do it now before there is any chance of a default setup hardcoding crap.
- log = logging.getLogger()
- fmt = logging.Formatter('%(asctime)s | %(levelname)-8s | %(message)s',
- '%Y-%m-%d %H:%M:%S %Z')
- stderr = logging.StreamHandler(stream=sys.stderr)
- stderr.setFormatter(fmt)
- log.addHandler(stderr)
- log.setLevel(logging.WARNING)
-
- parser = PodmanArgumentParser()
- args = parser.parse_args()
-
- log.setLevel(args.log_level)
- logging.debug(
- 'Logging initialized at level %s',
- logging.getLevelName(logging.getLogger().getEffectiveLevel()))
-
- def want_tb():
- """Add traceback when logging events."""
- return log.getEffectiveLevel() == logging.DEBUG
-
- try:
- if not os.path.exists(args.run_dir):
- os.makedirs(args.run_dir)
- except PermissionError as e:
- logging.critical(e, exc_info=want_tb())
- sys.exit(6)
-
- # class_(args).method() are set by the sub-command's parser
- returncode = None
- try:
- obj = args.class_(args)
- except AttributeError:
- parser.print_help(sys.stderr)
- sys.exit(1)
- except ValueError as e:
- print(e, file=sys.stderr, flush=True)
- sys.exit(1)
- except Exception as e: # pylint: disable=broad-except
- logging.critical(repr(e), exc_info=want_tb())
- logging.warning('See subparser "%s" configuration.',
- args.subparser_name)
- sys.exit(5)
-
- try:
- returncode = getattr(obj, args.method)()
- except KeyboardInterrupt:
- pass
- except AttributeError as e:
- logging.critical(e, exc_info=want_tb())
- logging.warning('See subparser "%s" configuration.',
- args.subparser_name)
- returncode = 3
- except (
- CalledProcessError,
- ConnectionError,
- ConnectionRefusedError,
- ConnectionResetError,
- TimeoutError,
- ) as e:
- logging.critical(e, exc_info=want_tb())
- logging.info('Review connection arguments for correctness.')
- returncode = 4
-
- return 0 if returncode is None else returncode
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/contrib/python/pypodman/pypodman/test/test_report.py b/contrib/python/pypodman/pypodman/test/test_report.py
deleted file mode 100644
index 280a9a954..000000000
--- a/contrib/python/pypodman/pypodman/test/test_report.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from __future__ import absolute_import
-
-import unittest
-
-from report import Report, ReportColumn
-
-
-class TestReport(unittest.TestCase):
- def setUp(self):
- pass
-
- def test_report_column(self):
- rc = ReportColumn('k', 'v', 3)
- self.assertEqual(rc.key, 'k')
- self.assertEqual(rc.display, 'v')
- self.assertEqual(rc.width, 3)
- self.assertIsNone(rc.default)
-
- rc = ReportColumn('k', 'v', 3, 'd')
- self.assertEqual(rc.key, 'k')
- self.assertEqual(rc.display, 'v')
- self.assertEqual(rc.width, 3)
- self.assertEqual(rc.default, 'd')
diff --git a/contrib/python/pypodman/requirements.txt b/contrib/python/pypodman/requirements.txt
deleted file mode 100644
index ba01ed36e..000000000
--- a/contrib/python/pypodman/requirements.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-humanize
-podman
-pytoml
-PyYAML
-setuptools>=39
diff --git a/contrib/python/pypodman/setup.py b/contrib/python/pypodman/setup.py
deleted file mode 100755
index f07e89201..000000000
--- a/contrib/python/pypodman/setup.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-import os
-
-from setuptools import find_packages, setup
-
-root = os.path.abspath(os.path.dirname(__file__))
-
-with open(os.path.join(root, 'README.md')) as me:
- readme = me.read()
-
-with open(os.path.join(root, 'requirements.txt')) as r:
- requirements = r.read().splitlines()
-
-
-setup(
- name='pypodman',
- version=os.environ.get('PODMAN_VERSION', '0.0.0'),
- description='A client for communicating with a Podman server',
- author_email='jhonce@redhat.com',
- author='Jhon Honce',
- license='Apache Software License',
- long_description=readme,
- entry_points={'console_scripts': [
- 'pypodman = pypodman.main:main',
- ]},
- include_package_data=True,
- install_requires=requirements,
- packages=find_packages(exclude=['test']),
- python_requires='>=3',
- zip_safe=True,
- url='http://github.com/containers/libpod',
- keywords='varlink libpod podman pypodman',
- classifiers=[
- 'Development Status :: 3 - Alpha',
- 'Intended Audience :: Developers',
- 'Intended Audience :: System Administrators',
- 'License :: OSI Approved :: Apache Software License',
- 'Operating System :: MacOS :: MacOS X',
- 'Operating System :: Microsoft :: Windows',
- 'Operating System :: POSIX',
- 'Programming Language :: Python :: 3.4',
- 'Topic :: System :: Systems Administration',
- 'Topic :: Utilities',
- ])
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 20e2a84ea..16cf01976 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -185,37 +185,6 @@ Provides: bundled(golang(k8s.io/utils)) = 258e2a2fa64568210fbd6267cf1d8fd87c3cb8
%{repo} provides a library for applications looking to use
the Container Pod concept popularized by Kubernetes.
-%if %{with varlink}
-%package -n python3-%{name}
-BuildArch: noarch
-BuildRequires: python3-devel
-BuildRequires: python3-setuptools
-BuildRequires: python3-varlink
-Requires: python3-setuptools
-Requires: python3-varlink
-Requires: python3-dateutil
-Requires: python3-humanize
-Provides: python3-%{name} = %{version}-%{release}
-Summary: Python 3 bindings for %{name}
-
-%description -n python3-%{name}
-This package contains Python 3 bindings for %{name}.
-
-%package -n python3-py%{name}
-BuildArch: noarch
-BuildRequires: python3-devel
-BuildRequires: python3-setuptools
-BuildRequires: python3-varlink
-Requires: python3-setuptools
-Requires: python3-varlink
-Requires: python3-dateutil
-Requires: python3-psutil
-Summary: Python 3 tool for %{name}
-
-%description -n python3-py%{name}
-This package contains Python 3 tool for %{name}.
-%endif # varlink
-
%if 0%{?with_devel}
%package devel
Summary: Library for applications looking to use Container Pods
@@ -421,10 +390,6 @@ PODMAN_VERSION=%{version} %{__make} PREFIX=%{buildroot}%{_prefix} ETCDIR=%{build
mv pkg/hooks/README.md pkg/hooks/README-hooks.md
-%if %{with varlink}
-PODMAN_VERSION=%{version} %{__make} DESTDIR=%{buildroot} install.python
-%endif # varlink
-
# install libpod.conf
install -dp %{buildroot}%{_datadir}/containers
install -p -m 644 %{repo}.conf %{buildroot}%{_datadir}/containers
@@ -514,23 +479,6 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/vendor:%{gopath}
%{_unitdir}/io.podman.socket
%{_usr}/lib/tmpfiles.d/%{name}.conf
-%if %{with varlink}
-%files -n python3-%{name}
-%license LICENSE
-%doc README.md CONTRIBUTING.md pkg/hooks/README-hooks.md install.md code-of-conduct.md transfer.md
-%dir %{python3_sitelib}/%{name}
-%{python3_sitelib}/%{name}/*
-%{python3_sitelib}/%{name}*.egg-info
-
-%files -n python3-py%{name}
-%license LICENSE
-%doc README.md CONTRIBUTING.md pkg/hooks/README-hooks.md install.md code-of-conduct.md transfer.md
-%dir %{python3_sitelib}/py%{name}
-%{python3_sitelib}/py%{name}/*
-%{python3_sitelib}/py%{name}*.egg-info
-%{_bindir}/py%{name}
-%endif # varlink
-
%if 0%{?with_devel}
%files -n libpod-devel -f devel.file-list
%license LICENSE
diff --git a/test/install/Dockerfile.Centos b/test/install/Dockerfile.Centos
index 11f60029b..608d3c971 100644
--- a/test/install/Dockerfile.Centos
+++ b/test/install/Dockerfile.Centos
@@ -1,3 +1,3 @@
FROM registry.centos.org/centos/centos:7
-RUN yum install -y rpms/noarch/* rpms/x86_64/* \ No newline at end of file
+RUN yum install -y rpms/x86_64/*
diff --git a/test/install/Dockerfile.Fedora b/test/install/Dockerfile.Fedora
index 3a7b472de..74cee771d 100644
--- a/test/install/Dockerfile.Fedora
+++ b/test/install/Dockerfile.Fedora
@@ -1,3 +1,3 @@
FROM registry.fedoraproject.org/fedora:29
-RUN dnf install -y rpms/noarch/* rpms/x86_64/*
+RUN dnf install -y rpms/x86_64/*