summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml2
-rw-r--r--.github/ISSUE_TEMPLATE.md6
-rwxr-xr-xAPI.md10
-rw-r--r--Dockerfile2
-rw-r--r--Dockerfile.centos2
-rw-r--r--Dockerfile.fedora2
-rw-r--r--cmd/podman/commands.go7
-rw-r--r--cmd/podman/commands_remoteclient.go5
-rw-r--r--cmd/podman/healthcheck.go5
-rw-r--r--cmd/podman/shared/funcs.go8
-rw-r--r--cmd/podman/varlink.go2
-rw-r--r--cmd/podman/varlink/io.podman.varlink7
-rw-r--r--cmd/podman/volume_create.go1
-rw-r--r--cmd/podman/volume_inspect.go24
-rw-r--r--docs/podman-build.1.md24
-rw-r--r--docs/podman-create.1.md21
-rw-r--r--docs/podman-run.1.md11
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--libpod.conf2
-rw-r--r--libpod/image/pull.go25
-rw-r--r--libpod/oci.go12
-rw-r--r--libpod/oci_internal_linux.go16
-rw-r--r--libpod/oci_linux.go6
-rw-r--r--libpod/options.go44
-rw-r--r--libpod/runtime.go6
-rw-r--r--libpod/runtime_volume_linux.go7
-rw-r--r--libpod/volume.go46
-rw-r--r--libpod/volume_inspect.go70
-rw-r--r--pkg/adapter/containers.go8
-rw-r--r--pkg/adapter/runtime.go14
-rw-r--r--pkg/adapter/runtime_remote.go5
-rw-r--r--pkg/adapter/volumes_remote.go2
-rw-r--r--pkg/util/utils_supported.go6
-rw-r--r--pkg/util/utils_windows.go8
-rw-r--r--pkg/varlinkapi/containers.go15
-rw-r--r--pkg/varlinkapi/volumes.go1
-rw-r--r--test/e2e/exec_test.go8
-rw-r--r--test/e2e/healthcheck_run_test.go2
-rw-r--r--test/e2e/libpod_suite_remoteclient_test.go7
-rw-r--r--test/e2e/libpod_suite_test.go7
-rw-r--r--test/e2e/pull_test.go28
-rw-r--r--test/e2e/run_exit_test.go4
-rw-r--r--test/e2e/run_selinux_test.go12
-rw-r--r--test/e2e/run_test.go2
-rw-r--r--test/e2e/start_test.go4
-rw-r--r--test/system/070-build.bats16
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go18
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go14
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go13
-rw-r--r--vendor/modules.txt4
51 files changed, 400 insertions, 177 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 5a9dbcb54..80c954ca0 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -371,6 +371,8 @@ testing_crun_task:
networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
install_crun_script: 'dnf install -y crun'
+ # FIXME: use the package once all the fixes are in a release
+ override_crun_script: 'setenforce 0; yum builddep -y crun && (git clone --depth=1 https://github.com/containers/crun && cd crun && ./autogen.sh && ./configure --prefix=/usr && make -j4 && make install) && rm -rf crun'
unit_test_script: '$SCRIPT_BASE/unit_test.sh |& ${TIMESTAMP}'
integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}'
system_test_script: '$SCRIPT_BASE/system_test.sh |& ${TIMESTAMP}'
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 2946f0b91..621430670 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -58,4 +58,10 @@ Briefly describe the problem you are having in a few paragraphs.
(paste your output here)
```
+**Package info (e.g. output of `rpm -q podman` or `apt list podman`):**
+
+```
+(paste your output here)
+```
+
**Additional environment details (AWS, VirtualBox, physical, etc.):**
diff --git a/API.md b/API.md
index 4afa18b45..c3a6ea4c8 100755
--- a/API.md
+++ b/API.md
@@ -87,6 +87,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func GetVolumes(args: []string, all: bool) Volume](#GetVolumes)
+[func HealthCheckRun(nameOrID: string) string](#HealthCheckRun)
+
[func HistoryImage(name: string) ImageHistory](#HistoryImage)
[func ImageExists(name: string) int](#ImageExists)
@@ -681,6 +683,12 @@ GetVersion returns version and build information of the podman service
method GetVolumes(args: [[]string](#[]string), all: [bool](https://godoc.org/builtin#bool)) [Volume](#Volume)</div>
GetVolumes gets slice of the volumes on a remote host
+### <a name="HealthCheckRun"></a>func HealthCheckRun
+<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
+
+method HealthCheckRun(nameOrID: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
+HealthCheckRun executes defined container's healthcheck command
+and returns the container's health status.
### <a name="HistoryImage"></a>func HistoryImage
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@@ -1981,8 +1989,6 @@ mountPoint [string](https://godoc.org/builtin#string)
driver [string](https://godoc.org/builtin#string)
options [map[string]](#map[string])
-
-scope [string](https://godoc.org/builtin#string)
### <a name="VolumeCreateOpts"></a>type VolumeCreateOpts
diff --git a/Dockerfile b/Dockerfile
index 3185586b9..40726ae09 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -68,7 +68,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install CNI plugins
-ENV CNI_COMMIT 7480240de9749f9a0a5c8614b17f1f03e0c06ab9
+ENV CNI_COMMIT 485be65581341430f9106a194a98f0f2412245fb
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/containernetworking/plugins.git "$GOPATH/src/github.com/containernetworking/plugins" \
diff --git a/Dockerfile.centos b/Dockerfile.centos
index bbb582840..f0d184485 100644
--- a/Dockerfile.centos
+++ b/Dockerfile.centos
@@ -27,7 +27,7 @@ RUN yum -y install btrfs-progs-devel \
iptables && yum clean all
# Install CNI plugins
-ENV CNI_COMMIT 7480240de9749f9a0a5c8614b17f1f03e0c06ab9
+ENV CNI_COMMIT 485be65581341430f9106a194a98f0f2412245fb
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/containernetworking/plugins.git "$GOPATH/src/github.com/containernetworking/plugins" \
diff --git a/Dockerfile.fedora b/Dockerfile.fedora
index 54ab690e9..48ca78bb5 100644
--- a/Dockerfile.fedora
+++ b/Dockerfile.fedora
@@ -30,7 +30,7 @@ RUN dnf -y install btrfs-progs-devel \
iptables && dnf clean all
# Install CNI plugins
-ENV CNI_COMMIT 412b6d31280682bb4fab4446f113c22ff1886554
+ENV CNI_COMMIT 485be65581341430f9106a194a98f0f2412245fb
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/containernetworking/plugins.git "$GOPATH/src/github.com/containernetworking/plugins" \
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index 27f3fc214..e23918a5b 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -71,10 +71,3 @@ func getSystemSubCommands() []*cobra.Command {
_migrateCommand,
}
}
-
-// Commands that the local client implements
-func getHealthcheckSubCommands() []*cobra.Command {
- return []*cobra.Command{
- _healthcheckrunCommand,
- }
-}
diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go
index 278fe229c..a278761c1 100644
--- a/cmd/podman/commands_remoteclient.go
+++ b/cmd/podman/commands_remoteclient.go
@@ -47,8 +47,3 @@ func getTrustSubCommands() []*cobra.Command {
func getSystemSubCommands() []*cobra.Command {
return []*cobra.Command{}
}
-
-// Commands that the remoteclient implements
-func getHealthcheckSubCommands() []*cobra.Command {
- return []*cobra.Command{}
-}
diff --git a/cmd/podman/healthcheck.go b/cmd/podman/healthcheck.go
index 9fb099ffa..140206dbe 100644
--- a/cmd/podman/healthcheck.go
+++ b/cmd/podman/healthcheck.go
@@ -16,11 +16,12 @@ var healthcheckCommand = cliconfig.PodmanCommand{
}
// Commands that are universally implemented
-var healthcheckCommands []*cobra.Command
+var healthcheckCommands = []*cobra.Command{
+ _healthcheckrunCommand,
+}
func init() {
healthcheckCommand.AddCommand(healthcheckCommands...)
- healthcheckCommand.AddCommand(getHealthcheckSubCommands()...)
healthcheckCommand.SetUsageTemplate(UsageTemplate())
rootCmd.AddCommand(healthcheckCommand.Command)
}
diff --git a/cmd/podman/shared/funcs.go b/cmd/podman/shared/funcs.go
index 2ceb9cdcb..bb4eed1e3 100644
--- a/cmd/podman/shared/funcs.go
+++ b/cmd/podman/shared/funcs.go
@@ -6,6 +6,7 @@ import (
"path/filepath"
"strings"
+ "github.com/containers/libpod/pkg/util"
"github.com/google/shlex"
)
@@ -13,13 +14,14 @@ func GetAuthFile(authfile string) string {
if authfile != "" {
return authfile
}
+
authfile = os.Getenv("REGISTRY_AUTH_FILE")
if authfile != "" {
return authfile
}
- runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
- if runtimeDir != "" {
- return filepath.Join(runtimeDir, "containers/auth.json")
+
+ if runtimeDir, err := util.GetRuntimeDir(); err == nil {
+ return filepath.Join(runtimeDir, "auth.json")
}
return ""
}
diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go
index 5f89534be..cd21e3574 100644
--- a/cmd/podman/varlink.go
+++ b/cmd/podman/varlink.go
@@ -53,7 +53,7 @@ func init() {
func varlinkCmd(c *cliconfig.VarlinkValues) error {
varlinkURI := adapter.DefaultAddress
if rootless.IsRootless() {
- xdg, err := util.GetRootlessRuntimeDir()
+ xdg, err := util.GetRuntimeDir()
if err != nil {
return err
}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 2e7dee94d..1b10416a2 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -7,8 +7,7 @@ type Volume (
labels: [string]string,
mountPoint: string,
driver: string,
- options: [string]string,
- scope: string
+ options: [string]string
)
type NotImplemented (
@@ -545,6 +544,10 @@ method GetContainersByStatus(status: []string) -> (containerS: []Container)
method Top (nameOrID: string, descriptors: []string) -> (top: []string)
+# HealthCheckRun executes defined container's healthcheck command
+# and returns the container's health status.
+method HealthCheckRun (nameOrID: string) -> (healthCheckStatus: string)
+
# GetContainer returns information about a single container. If a container
# with the given id doesn't exist, a [ContainerNotFound](#ContainerNotFound)
# error will be returned. See also [ListContainers](ListContainers) and
diff --git a/cmd/podman/volume_create.go b/cmd/podman/volume_create.go
index 0897ab705..617f701a4 100644
--- a/cmd/podman/volume_create.go
+++ b/cmd/podman/volume_create.go
@@ -38,7 +38,6 @@ func init() {
flags.StringVar(&volumeCreateCommand.Driver, "driver", "", "Specify volume driver name (default local)")
flags.StringSliceVarP(&volumeCreateCommand.Label, "label", "l", []string{}, "Set metadata for a volume (default [])")
flags.StringSliceVarP(&volumeCreateCommand.Opt, "opt", "o", []string{}, "Set driver specific options (default [])")
-
}
func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error {
diff --git a/cmd/podman/volume_inspect.go b/cmd/podman/volume_inspect.go
index 1ebc5ce60..94c99a58c 100644
--- a/cmd/podman/volume_inspect.go
+++ b/cmd/podman/volume_inspect.go
@@ -1,6 +1,9 @@
package main
import (
+ "fmt"
+
+ "github.com/containers/buildah/pkg/formats"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
"github.com/pkg/errors"
@@ -53,5 +56,24 @@ func volumeInspectCmd(c *cliconfig.VolumeInspectValues) error {
if err != nil {
return err
}
- return generateVolLsOutput(vols, volumeLsOptions{Format: c.Format})
+
+ switch c.Format {
+ case "", formats.JSONString:
+ // Normal format - JSON string
+ jsonOut, err := json.MarshalIndent(vols, "", " ")
+ if err != nil {
+ return errors.Wrapf(err, "error marshalling inspect JSON")
+ }
+ fmt.Println(string(jsonOut))
+ default:
+ // It's a Go template.
+ interfaces := make([]interface{}, len(vols))
+ for i, vol := range vols {
+ interfaces[i] = vol
+ }
+ out := formats.StdoutTemplateArray{Output: interfaces, Template: c.Format}
+ return out.Out()
+ }
+
+ return nil
}
diff --git a/docs/podman-build.1.md b/docs/podman-build.1.md
index 878b31080..8deb8811e 100644
--- a/docs/podman-build.1.md
+++ b/docs/podman-build.1.md
@@ -375,18 +375,18 @@ to podman build, the option given would be `--runtime-flag log-format=json`.
Security Options
- "label=user:USER" : Set the label user for the container
- "label=role:ROLE" : Set the label role for the container
- "label=type:TYPE" : Set the label type for the container
- "label=level:LEVEL" : Set the label level for the container
- "label=disable" : Turn off label confinement for the container
- "no-new-privileges" : Not supported
-
- "seccomp=unconfined" : Turn off seccomp confinement for the container
- "seccomp=profile.json : White listed syscalls seccomp Json file to be used as a seccomp filter
-
- "apparmor=unconfined" : Turn off apparmor confinement for the container
- "apparmor=your-profile" : Set the apparmor confinement profile for the container
+- `apparmor=unconfined` : Turn off apparmor confinement for the container
+- `apparmor=your-profile` : Set the apparmor confinement profile for the container
+
+- `label=user:USER` : Set the label user for the container processes
+- `label=role:ROLE` : Set the label role for the container processes
+- `label=type:TYPE` : Set the label process type for the container processes
+- `label=level:LEVEL` : Set the label level for the container processes
+- `label=filetype:TYPE` : Set the label file type for the container files
+- `label=disable` : Turn off label separation for the container
+
+- `seccomp=unconfined` : Turn off seccomp confinement for the container
+- `seccomp=profile.json` : White listed syscalls seccomp Json file to be used as a seccomp filter
**--shm-size**=*size*
diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index 1377f2a03..7634408f5 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -640,19 +640,20 @@ of the container is assumed to be managed externally.
Security Options
-"apparmor=unconfined" : Turn off apparmor confinement for the container
-"apparmor=your-profile" : Set the apparmor confinement profile for the container
+- `apparmor=unconfined` : Turn off apparmor confinement for the container
+- `apparmor=your-profile` : Set the apparmor confinement profile for the container
-"label=user:USER" : Set the label user for the container
-"label=role:ROLE" : Set the label role for the container
-"label=type:TYPE" : Set the label type for the container
-"label=level:LEVEL" : Set the label level for the container
-"label=disable" : Turn off label confinement for the container
+- `label=user:USER` : Set the label user for the container processes
+- `label=role:ROLE` : Set the label role for the container processes
+- `label=type:TYPE` : Set the label process type for the container processes
+- `label=level:LEVEL` : Set the label level for the container processes
+- `label=filetype:TYPE` : Set the label file type for the container files
+- `label=disable` : Turn off label separation for the container
-"no-new-privileges" : Disable container processes from gaining additional privileges
+- `no-new-privileges` : Disable container processes from gaining additional privileges
-"seccomp=unconfined" : Turn off seccomp confinement for the container
-"seccomp=profile.json : White listed syscalls seccomp Json file to be used as a seccomp filter
+- `seccomp=unconfined` : Turn off seccomp confinement for the container
+- `seccomp=profile.json` : White listed syscalls seccomp Json file to be used as a seccomp filter
Note: Labeling can be disabled for all containers by setting label=false in the **libpod.conf** (`/etc/containers/libpod.conf`) file.
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index 2445df566..33b5cbf9e 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -665,11 +665,12 @@ Security Options
- `apparmor=unconfined` : Turn off apparmor confinement for the container
- `apparmor=your-profile` : Set the apparmor confinement profile for the container
-- `label=user:USER` : Set the label user for the container
-- `label=role:ROLE` : Set the label role for the container
-- `label=type:TYPE` : Set the label type for the container
-- `label=level:LEVEL` : Set the label level for the container
-- `label=disable` : Turn off label confinement for the container
+- `label=user:USER` : Set the label user for the container processes
+- `label=role:ROLE` : Set the label role for the container processes
+- `label=type:TYPE` : Set the label process type for the container processes
+- `label=level:LEVEL` : Set the label level for the container processes
+- `label=filetype:TYPE` : Set the label file type for the container files
+- `label=disable` : Turn off label separation for the container
- `no-new-privileges` : Disable container processes from gaining additional privileges
diff --git a/go.mod b/go.mod
index 00e1c1cf4..5f3b3ea66 100644
--- a/go.mod
+++ b/go.mod
@@ -69,7 +69,7 @@ require (
github.com/opencontainers/runc v1.0.0-rc8
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7
github.com/opencontainers/runtime-tools v0.9.0
- github.com/opencontainers/selinux v1.2.2
+ github.com/opencontainers/selinux v1.3.0
github.com/opentracing/opentracing-go v1.1.0
github.com/pelletier/go-toml v1.4.0 // indirect
github.com/pkg/errors v0.8.1
diff --git a/go.sum b/go.sum
index f09083eb7..e837f0efc 100644
--- a/go.sum
+++ b/go.sum
@@ -394,6 +394,8 @@ github.com/opencontainers/selinux v0.0.0-20190118194635-b707dfcb00a1 h1:V8Icxoi2
github.com/opencontainers/selinux v0.0.0-20190118194635-b707dfcb00a1/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
github.com/opencontainers/selinux v1.2.2 h1:Kx9J6eDG5/24A6DtUquGSpJQ+m2MUTahn4FtGEe8bFg=
github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
+github.com/opencontainers/selinux v1.3.0 h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g=
+github.com/opencontainers/selinux v1.3.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
github.com/openshift/imagebuilder v1.1.0 h1:oT704SkwMEzmIMU/+Uv1Wmvt+p10q3v2WuYMeFI18c4=
github.com/openshift/imagebuilder v1.1.0/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
github.com/opentracing/opentracing-go v0.0.0-20190218023034-25a84ff92183 h1:kwFCLTA0DYhH0JpGMBOZtVVhyRL5ec+unn4mnoJhQI0=
@@ -440,6 +442,8 @@ github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNG
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/prometheus/tsdb v0.8.0/go.mod h1:fSI0j+IUQrDd7+ZtR9WKIGtoYAYAJUKcKhYLG25tN4g=
+github.com/rhatdan/oci-selinux v0.0.0-20190809194358-225b95ae1d0b h1:9CE1lDQ/YC1deOJE/elAI+nbE1OzOxSvrs6JXwyn+1s=
+github.com/rhatdan/oci-selinux v0.0.0-20190809194358-225b95ae1d0b/go.mod h1:T/CPBeRZLtTvck9OtpX3PGw/uDABnTuRPhyTacu5aSo=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
diff --git a/libpod.conf b/libpod.conf
index 3bd3758b8..81fece5d2 100644
--- a/libpod.conf
+++ b/libpod.conf
@@ -120,7 +120,7 @@ runtime = "runc"
# List of the OCI runtimes that support --format=json. When json is supported
# libpod will use it for reporting nicer errors.
-runtime_supports_json = ["runc"]
+runtime_supports_json = ["crun", "runc"]
# Paths to look for a valid OCI runtime (runc, runv, etc)
# If the paths are empty or no valid path was found, then the `$PATH`
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index 78cfe3626..dbf3a4ef5 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -13,6 +13,7 @@ import (
dockerarchive "github.com/containers/image/docker/archive"
"github.com/containers/image/docker/tarfile"
ociarchive "github.com/containers/image/oci/archive"
+ oci "github.com/containers/image/oci/layout"
is "github.com/containers/image/storage"
"github.com/containers/image/transports"
"github.com/containers/image/transports/alltransports"
@@ -37,6 +38,9 @@ var (
DirTransport = directory.Transport.Name()
// DockerTransport is the transport for docker registries
DockerTransport = docker.Transport.Name()
+ // OCIDirTransport is the transport for pushing and pulling
+ // images to and from a directory containing an OCI image
+ OCIDirTransport = oci.Transport.Name()
// AtomicTransport is the transport for atomic registries
AtomicTransport = "atomic"
// DefaultTransport is a prefix that we apply to an image name
@@ -189,12 +193,12 @@ func (ir *Runtime) pullGoalFromImageReference(ctx context.Context, srcRef types.
return ir.getSinglePullRefPairGoal(srcRef, dest)
case DirTransport:
- path := srcRef.StringWithinTransport()
- image := path
- if image[:1] == "/" {
- // Set localhost as the registry so docker.io isn't prepended, and the path becomes the repository
- image = DefaultLocalRegistry + image
- }
+ image := toLocalImageName(srcRef.StringWithinTransport())
+ return ir.getSinglePullRefPairGoal(srcRef, image)
+
+ case OCIDirTransport:
+ split := strings.SplitN(srcRef.StringWithinTransport(), ":", 2)
+ image := toLocalImageName(split[0])
return ir.getSinglePullRefPairGoal(srcRef, image)
default:
@@ -202,6 +206,15 @@ func (ir *Runtime) pullGoalFromImageReference(ctx context.Context, srcRef types.
}
}
+// toLocalImageName converts an image name into a 'localhost/' prefixed one
+func toLocalImageName(imageName string) string {
+ return fmt.Sprintf(
+ "%s/%s",
+ DefaultLocalRegistry,
+ strings.TrimLeft(imageName, "/"),
+ )
+}
+
// pullImageFromHeuristicSource pulls an image based on inputName, which is heuristically parsed and may involve configured registries.
// Use pullImageFromReference if the source is known precisely.
func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName string, writer io.Writer, authfile, signaturePolicyPath string, signingOptions SigningOptions, dockerOptions *DockerRegistryOptions, label *string) ([]string, error) {
diff --git a/libpod/oci.go b/libpod/oci.go
index 4ba3114e3..8a873ca5b 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -213,7 +213,7 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) {
func (r *OCIRuntime) updateContainerStatus(ctr *Container, useRuntime bool) error {
exitFile := ctr.exitFilePath()
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
@@ -336,7 +336,7 @@ func (r *OCIRuntime) updateContainerStatus(ctr *Container, useRuntime bool) erro
// Sets time the container was started, but does not save it.
func (r *OCIRuntime) startContainer(ctr *Container) error {
// TODO: streams should probably *not* be our STDIN/OUT/ERR - redirect to buffers?
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
@@ -356,7 +356,7 @@ func (r *OCIRuntime) startContainer(ctr *Container) error {
// killContainer sends the given signal to the given container
func (r *OCIRuntime) killContainer(ctr *Container, signal uint) error {
logrus.Debugf("Sending signal %d to container %s", signal, ctr.ID())
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
@@ -370,7 +370,7 @@ func (r *OCIRuntime) killContainer(ctr *Container, signal uint) error {
// deleteContainer deletes a container from the OCI runtime
func (r *OCIRuntime) deleteContainer(ctr *Container) error {
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
@@ -380,7 +380,7 @@ func (r *OCIRuntime) deleteContainer(ctr *Container) error {
// pauseContainer pauses the given container
func (r *OCIRuntime) pauseContainer(ctr *Container) error {
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
@@ -390,7 +390,7 @@ func (r *OCIRuntime) pauseContainer(ctr *Container) error {
// unpauseContainer unpauses the given container
func (r *OCIRuntime) unpauseContainer(ctr *Container) error {
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
diff --git a/libpod/oci_internal_linux.go b/libpod/oci_internal_linux.go
index 6e4ee2cf2..48b7370e0 100644
--- a/libpod/oci_internal_linux.go
+++ b/libpod/oci_internal_linux.go
@@ -36,7 +36,7 @@ import (
func (r *OCIRuntime) createOCIContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) (err error) {
var stderrBuf bytes.Buffer
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
@@ -449,6 +449,15 @@ func readConmonPipeData(pipe *os.File, ociLog string) (int, error) {
select {
case ss := <-ch:
if ss.err != nil {
+ if ociLog != "" {
+ ociLogData, err := ioutil.ReadFile(ociLog)
+ if err == nil {
+ var ociErr ociError
+ if err := json.Unmarshal(ociLogData, &ociErr); err == nil {
+ return -1, getOCIRuntimeError(ociErr.Msg)
+ }
+ }
+ }
return -1, errors.Wrapf(ss.err, "error reading container (probably exited) json message")
}
logrus.Debugf("Received: %d", ss.si.Data)
@@ -476,10 +485,11 @@ func readConmonPipeData(pipe *os.File, ociLog string) (int, error) {
}
func getOCIRuntimeError(runtimeMsg string) error {
- if match, _ := regexp.MatchString(".*permission denied.*", runtimeMsg); match {
+ r := strings.ToLower(runtimeMsg)
+ if match, _ := regexp.MatchString(".*permission denied.*|.*operation not permitted.*", r); match {
return errors.Wrapf(define.ErrOCIRuntimePermissionDenied, "%s", strings.Trim(runtimeMsg, "\n"))
}
- if match, _ := regexp.MatchString(".*executable file not found in.*", runtimeMsg); match {
+ if match, _ := regexp.MatchString(".*executable file not found in.*|.*no such file or directory.*", r); match {
return errors.Wrapf(define.ErrOCIRuntimeNotFound, "%s", strings.Trim(runtimeMsg, "\n"))
}
return errors.Wrapf(define.ErrOCIRuntime, "%s", strings.Trim(runtimeMsg, "\n"))
diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go
index 45365203e..1613c3e68 100644
--- a/libpod/oci_linux.go
+++ b/libpod/oci_linux.go
@@ -208,7 +208,7 @@ func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty
}
}()
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return -1, nil, err
}
@@ -437,7 +437,7 @@ func (r *OCIRuntime) stopContainer(ctr *Container, timeout uint) error {
args = []string{"kill", "--all", ctr.ID(), "KILL"}
}
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
@@ -487,7 +487,7 @@ func (r *OCIRuntime) execStopContainer(ctr *Container, timeout uint) error {
if len(execSessions) == 0 {
return nil
}
- runtimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
}
diff --git a/libpod/options.go b/libpod/options.go
index d2a67e38c..a7ddbec34 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1371,6 +1371,17 @@ func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption {
}
}
+// WithHealthCheck adds the healthcheck to the container config
+func WithHealthCheck(healthCheck *manifest.Schema2HealthConfig) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+ ctr.config.HealthCheckConfig = healthCheck
+ return nil
+ }
+}
+
// Volume Creation Options
// WithVolumeName sets the name of the volume.
@@ -1390,30 +1401,30 @@ func WithVolumeName(name string) VolumeCreateOption {
}
}
-// WithVolumeLabels sets the labels of the volume.
-func WithVolumeLabels(labels map[string]string) VolumeCreateOption {
+// WithVolumeDriver sets the volume's driver.
+// It is presently not implemented, but will be supported in a future Podman
+// release.
+func WithVolumeDriver(driver string) VolumeCreateOption {
return func(volume *Volume) error {
if volume.valid {
return define.ErrVolumeFinalized
}
- volume.config.Labels = make(map[string]string)
- for key, value := range labels {
- volume.config.Labels[key] = value
- }
-
- return nil
+ return define.ErrNotImplemented
}
}
-// WithVolumeDriver sets the driver of the volume.
-func WithVolumeDriver(driver string) VolumeCreateOption {
+// WithVolumeLabels sets the labels of the volume.
+func WithVolumeLabels(labels map[string]string) VolumeCreateOption {
return func(volume *Volume) error {
if volume.valid {
return define.ErrVolumeFinalized
}
- volume.config.Driver = driver
+ volume.config.Labels = make(map[string]string)
+ for key, value := range labels {
+ volume.config.Labels[key] = value
+ }
return nil
}
@@ -1700,14 +1711,3 @@ func WithInfraContainerPorts(bindings []ocicni.PortMapping) PodCreateOption {
return nil
}
}
-
-// WithHealthCheck adds the healthcheck to the container config
-func WithHealthCheck(healthCheck *manifest.Schema2HealthConfig) CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return define.ErrCtrFinalized
- }
- ctr.config.HealthCheckConfig = healthCheck
- return nil
- }
-}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 2fa8dd424..cbbf667db 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -369,7 +369,7 @@ func SetXdgDirs() error {
if runtimeDir == "" {
var err error
- runtimeDir, err = util.GetRootlessRuntimeDir()
+ runtimeDir, err = util.GetRuntimeDir()
if err != nil {
return err
}
@@ -395,11 +395,11 @@ func getDefaultTmpDir() (string, error) {
return "/var/run/libpod", nil
}
- rootlessRuntimeDir, err := util.GetRootlessRuntimeDir()
+ runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return "", err
}
- libpodRuntimeDir := filepath.Join(rootlessRuntimeDir, "libpod")
+ libpodRuntimeDir := filepath.Join(runtimeDir, "libpod")
if err := os.Mkdir(libpodRuntimeDir, 0700|os.ModeSticky); err != nil {
if !os.IsExist(err) {
diff --git a/libpod/runtime_volume_linux.go b/libpod/runtime_volume_linux.go
index ac6fd02c3..84703787d 100644
--- a/libpod/runtime_volume_linux.go
+++ b/libpod/runtime_volume_linux.go
@@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"strings"
+ "time"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
@@ -42,14 +43,10 @@ func (r *Runtime) newVolume(ctx context.Context, options ...VolumeCreateOption)
if volume.config.Name == "" {
volume.config.Name = stringid.GenerateNonCryptoID()
}
- // TODO: support for other volume drivers
if volume.config.Driver == "" {
volume.config.Driver = "local"
}
- // TODO: determine when the scope is global and set it to that
- if volume.config.Scope == "" {
- volume.config.Scope = "local"
- }
+ volume.config.CreatedTime = time.Now()
// Create the mountpoint of this volume
volPathRoot := filepath.Join(r.config.VolumePath, volume.config.Name)
diff --git a/libpod/volume.go b/libpod/volume.go
index 9ed2ff087..74126b49b 100644
--- a/libpod/volume.go
+++ b/libpod/volume.go
@@ -1,5 +1,9 @@
package libpod
+import (
+ "time"
+)
+
// Volume is the type used to create named volumes
// TODO: all volumes should be created using this and the Volume API
type Volume struct {
@@ -15,10 +19,10 @@ type VolumeConfig struct {
Name string `json:"name"`
Labels map[string]string `json:"labels"`
- MountPoint string `json:"mountPoint"`
Driver string `json:"driver"`
+ MountPoint string `json:"mountPoint"`
+ CreatedTime time.Time `json:"createdAt,omitempty"`
Options map[string]string `json:"options"`
- Scope string `json:"scope"`
IsCtrSpecific bool `json:"ctrSpecific"`
UID int `json:"uid"`
GID int `json:"gid"`
@@ -29,6 +33,18 @@ func (v *Volume) Name() string {
return v.config.Name
}
+// Driver retrieves the volume's driver.
+func (v *Volume) Driver() string {
+ return v.config.Driver
+}
+
+// Scope retrieves the volume's scope.
+// Libpod does not implement volume scoping, and this is provided solely for
+// Docker compatibility. It returns only "local".
+func (v *Volume) Scope() string {
+ return "local"
+}
+
// Labels returns the volume's labels
func (v *Volume) Labels() map[string]string {
labels := make(map[string]string)
@@ -43,11 +59,6 @@ func (v *Volume) MountPoint() string {
return v.config.MountPoint
}
-// Driver returns the volume's driver
-func (v *Volume) Driver() string {
- return v.config.Driver
-}
-
// Options return the volume's options
func (v *Volume) Options() map[string]string {
options := make(map[string]string)
@@ -58,14 +69,25 @@ func (v *Volume) Options() map[string]string {
return options
}
-// Scope returns the scope of the volume
-func (v *Volume) Scope() string {
- return v.config.Scope
-}
-
// IsCtrSpecific returns whether this volume was created specifically for a
// given container. Images with this set to true will be removed when the
// container is removed with the Volumes parameter set to true.
func (v *Volume) IsCtrSpecific() bool {
return v.config.IsCtrSpecific
}
+
+// UID returns the UID the volume will be created as.
+func (v *Volume) UID() int {
+ return v.config.UID
+}
+
+// GID returns the GID the volume will be created as.
+func (v *Volume) GID() int {
+ return v.config.GID
+}
+
+// CreatedTime returns the time the volume was created at. It was not tracked
+// for some time, so older volumes may not contain one.
+func (v *Volume) CreatedTime() time.Time {
+ return v.config.CreatedTime
+}
diff --git a/libpod/volume_inspect.go b/libpod/volume_inspect.go
new file mode 100644
index 000000000..87ed9d340
--- /dev/null
+++ b/libpod/volume_inspect.go
@@ -0,0 +1,70 @@
+package libpod
+
+import (
+ "time"
+
+ "github.com/containers/libpod/libpod/define"
+)
+
+// InspectVolumeData is the output of Inspect() on a volume. It is matched to
+// the format of 'docker volume inspect'.
+type InspectVolumeData struct {
+ // Name is the name of the volume.
+ Name string `json:"Name"`
+ // Driver is the driver used to create the volume.
+ // This will be properly implemented in a future version.
+ Driver string `json:"Driver"`
+ // Mountpoint is the path on the host where the volume is mounted.
+ Mountpoint string `json:"Mountpoint"`
+ // CreatedAt is the date and time the volume was created at. This is not
+ // stored for older Libpod volumes; if so, it will be omitted.
+ CreatedAt time.Time `json:"CreatedAt,omitempty"`
+ // Status is presently unused and provided only for Docker compatibility.
+ // In the future it will be used to return information on the volume's
+ // current state.
+ Status map[string]string `json:"Status,omitempty"`
+ // Labels includes the volume's configured labels, key:value pairs that
+ // can be passed during volume creation to provide information for third
+ // party tools.
+ Labels map[string]string `json:"Labels"`
+ // Scope is unused and provided solely for Docker compatibility. It is
+ // unconditionally set to "local".
+ Scope string `json:"Scope"`
+ // Options is a set of options that were used when creating the volume.
+ // It is presently not used.
+ Options map[string]string `json:"Options"`
+ // UID is the UID that the volume was created with.
+ UID int `json:"UID,omitempty"`
+ // GID is the GID that the volume was created with.
+ GID int `json:"GID,omitempty"`
+ // ContainerSpecific indicates that the volume was created as part of a
+ // specific container, and will be removed when that container is
+ // removed.
+ ContainerSpecific bool `json:"ContainerSpecific,omitempty"`
+}
+
+// Inspect provides detailed information about the configuration of the given
+// volume.
+func (v *Volume) Inspect() (*InspectVolumeData, error) {
+ if !v.valid {
+ return nil, define.ErrVolumeRemoved
+ }
+
+ data := new(InspectVolumeData)
+
+ data.Name = v.config.Name
+ data.Driver = v.config.Driver
+ data.Mountpoint = v.config.MountPoint
+ data.CreatedAt = v.config.CreatedTime
+ data.Labels = make(map[string]string)
+ for k, v := range v.config.Labels {
+ data.Labels[k] = v
+ }
+ data.Scope = v.Scope()
+ data.Options = make(map[string]string)
+ data.UID = v.config.UID
+ data.GID = v.config.GID
+ data.ContainerSpecific = v.config.IsCtrSpecific
+
+ return data, nil
+}
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 45a9a54a3..863640f97 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -342,7 +342,8 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
if err := ctr.Start(ctx, c.IsSet("pod")); err != nil {
// This means the command did not exist
exitCode = 127
- if strings.Contains(err.Error(), "permission denied") || strings.Contains(err.Error(), "file not found") {
+ e := strings.ToLower(err.Error())
+ if strings.Contains(e, "permission denied") || strings.Contains(e, "operation not permitted") || strings.Contains(e, "file not found") || strings.Contains(e, "no such file or directory") {
exitCode = 126
}
return exitCode, err
@@ -405,12 +406,13 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
}
// This means the command did not exist
exitCode = 127
- if strings.Contains(err.Error(), "permission denied") {
+ e := strings.ToLower(err.Error())
+ if strings.Contains(e, "permission denied") || strings.Contains(e, "operation not permitted") {
exitCode = 126
}
if c.IsSet("rm") {
if deleteError := r.Runtime.RemoveContainer(ctx, ctr, true, false); deleteError != nil {
- logrus.Errorf("unable to remove container %s after failing to start and attach to it", ctr.ID())
+ logrus.Debugf("unable to remove container %s after failing to start and attach to it", ctr.ID())
}
}
return exitCode, err
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index ba988aaf7..7d4f97b28 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -210,7 +210,7 @@ func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestM
}
// InspectVolumes returns a slice of volumes based on an arg list or --all
-func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*Volume, error) {
+func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*libpod.InspectVolumeData, error) {
var (
volumes []*libpod.Volume
err error
@@ -230,7 +230,17 @@ func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeIn
if err != nil {
return nil, err
}
- return libpodVolumeToVolume(volumes), nil
+
+ inspectVols := make([]*libpod.InspectVolumeData, 0, len(volumes))
+ for _, vol := range volumes {
+ inspectOut, err := vol.Inspect()
+ if err != nil {
+ return nil, errors.Wrapf(err, "error inspecting volume %s", vol.Name())
+ }
+ inspectVols = append(inspectVols, inspectOut)
+ }
+
+ return inspectVols, nil
}
// Volumes returns a slice of localruntime volumes
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index 420c9d0bb..683bf1d35 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -21,7 +21,7 @@ import (
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/remoteclientconfig"
- "github.com/containers/libpod/cmd/podman/varlink"
+ iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
@@ -669,7 +669,6 @@ func varlinkVolumeToVolume(r *LocalRuntime, volumes []iopodman.Volume) []*Volume
MountPoint: v.MountPoint,
Driver: v.Driver,
Options: v.Options,
- Scope: v.Scope,
}
n := remoteVolume{
Runtime: r,
@@ -813,7 +812,7 @@ func IsImageNotFound(err error) bool {
// HealthCheck executes a container's healthcheck over a varlink connection
func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (string, error) {
- return "", define.ErrNotImplemented
+ return iopodman.HealthCheckRun().Call(r.Conn, c.InputArgs[0])
}
// Events monitors libpod/podman events over a varlink connection
diff --git a/pkg/adapter/volumes_remote.go b/pkg/adapter/volumes_remote.go
index beacd943a..58f9ba625 100644
--- a/pkg/adapter/volumes_remote.go
+++ b/pkg/adapter/volumes_remote.go
@@ -29,5 +29,5 @@ func (v *Volume) MountPoint() string {
// Scope returns the scope for an adapter.volume
func (v *Volume) Scope() string {
- return v.config.Scope
+ return "local"
}
diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go
index c7c8787a0..707e193e9 100644
--- a/pkg/util/utils_supported.go
+++ b/pkg/util/utils_supported.go
@@ -16,8 +16,8 @@ import (
"github.com/sirupsen/logrus"
)
-// GetRootlessRuntimeDir returns the runtime directory when running as non root
-func GetRootlessRuntimeDir() (string, error) {
+// GetRuntimeDir returns the runtime directory
+func GetRuntimeDir() (string, error) {
var rootlessRuntimeDirError error
rootlessRuntimeDirOnce.Do(func() {
@@ -100,7 +100,7 @@ func GetRootlessConfigHomeDir() (string, error) {
// GetRootlessPauseProcessPidPath returns the path to the file that holds the pid for
// the pause process
func GetRootlessPauseProcessPidPath() (string, error) {
- runtimeDir, err := GetRootlessRuntimeDir()
+ runtimeDir, err := GetRuntimeDir()
if err != nil {
return "", err
}
diff --git a/pkg/util/utils_windows.go b/pkg/util/utils_windows.go
index e781e6717..9bba2d1ee 100644
--- a/pkg/util/utils_windows.go
+++ b/pkg/util/utils_windows.go
@@ -25,12 +25,12 @@ func GetRootlessPauseProcessPidPath() (string, error) {
return "", errors.Wrap(errNotImplemented, "GetRootlessPauseProcessPidPath")
}
-// GetRootlessRuntimeDir returns the runtime directory when running as non root
-func GetRootlessRuntimeDir() (string, error) {
- return "", errors.Wrap(errNotImplemented, "GetRootlessRuntimeDir")
+// GetRuntimeDir returns the runtime directory
+func GetRuntimeDir() (string, error) {
+ return "", errors.New("this function is not implemented for windows")
}
// GetRootlessConfigHomeDir returns the config home directory when running as non root
func GetRootlessConfigHomeDir() (string, error) {
- return "", errors.Wrap(errNotImplemented, "GetRootlessConfigHomeDir")
+ return "", errors.New("this function is not implemented for windows")
}
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index c7aa5233f..2dcdbc089 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -14,7 +14,7 @@ import (
"time"
"github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/cmd/podman/varlink"
+ iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/logs"
@@ -864,3 +864,16 @@ func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecO
return ecErr.Error
}
+
+//HealthCheckRun executes defined container's healthcheck command and returns the container's health status.
+func (i *LibpodAPI) HealthCheckRun(call iopodman.VarlinkCall, nameOrID string) error {
+ hcStatus, err := i.Runtime.HealthCheck(nameOrID)
+ if err != nil && hcStatus != libpod.HealthCheckFailure {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ status := libpod.HealthCheckUnhealthy
+ if hcStatus == libpod.HealthCheckSuccess {
+ status = libpod.HealthCheckHealthy
+ }
+ return call.ReplyHealthCheckRun(status)
+}
diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go
index 19ba38e7c..6dd86d831 100644
--- a/pkg/varlinkapi/volumes.go
+++ b/pkg/varlinkapi/volumes.go
@@ -68,7 +68,6 @@ func (i *LibpodAPI) GetVolumes(call iopodman.VarlinkCall, args []string, all boo
MountPoint: v.MountPoint(),
Name: v.Name(),
Options: v.Options(),
- Scope: v.Scope(),
}
volumes = append(volumes, newVol)
}
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index 3f9639fda..ac727f9bc 100644
--- a/test/e2e/exec_test.go
+++ b/test/e2e/exec_test.go
@@ -171,16 +171,14 @@ var _ = Describe("Podman exec", func() {
session := podmanTest.Podman([]string{"exec", "--workdir", "/missing", "test1", "pwd"})
session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(1))
+ Expect(session.ExitCode()).To(Not(Equal(0)))
session = podmanTest.Podman([]string{"exec", "-w", "/missing", "test1", "pwd"})
session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(1))
+ Expect(session.ExitCode()).To(Not(Equal(0)))
})
It("podman exec cannot be invoked", func() {
- SkipIfNotRunc()
-
setup := podmanTest.RunTopContainer("test1")
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
@@ -191,8 +189,6 @@ var _ = Describe("Podman exec", func() {
})
It("podman exec command not found", func() {
- SkipIfNotRunc()
-
setup := podmanTest.RunTopContainer("test1")
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(Equal(0))
diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go
index dafc8a837..e10aef427 100644
--- a/test/e2e/healthcheck_run_test.go
+++ b/test/e2e/healthcheck_run_test.go
@@ -1,5 +1,3 @@
-// +build !remoteclient
-
package integration
import (
diff --git a/test/e2e/libpod_suite_remoteclient_test.go b/test/e2e/libpod_suite_remoteclient_test.go
index a6cedfc58..7f33fec87 100644
--- a/test/e2e/libpod_suite_remoteclient_test.go
+++ b/test/e2e/libpod_suite_remoteclient_test.go
@@ -28,13 +28,6 @@ func SkipIfRootless() {
}
}
-func SkipIfNotRunc() {
- runtime := os.Getenv("OCI_RUNTIME")
- if runtime != "" && filepath.Base(runtime) != "runc" {
- ginkgo.Skip("Not using runc as runtime")
- }
-}
-
// Podman is the exec call to podman on the filesystem
func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration {
podmanSession := p.PodmanBase(args, false, false)
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
index 22cc14d6b..1df59dbe3 100644
--- a/test/e2e/libpod_suite_test.go
+++ b/test/e2e/libpod_suite_test.go
@@ -21,13 +21,6 @@ func SkipIfRootless() {
}
}
-func SkipIfNotRunc() {
- runtime := os.Getenv("OCI_RUNTIME")
- if runtime != "" && filepath.Base(runtime) != "runc" {
- ginkgo.Skip("Not using runc as runtime")
- }
-}
-
// Podman is the exec call to podman on the filesystem
func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration {
podmanSession := p.PodmanBase(args, false, false)
diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go
index d6e7b44d1..68fcaf133 100644
--- a/test/e2e/pull_test.go
+++ b/test/e2e/pull_test.go
@@ -150,6 +150,34 @@ var _ = Describe("Podman pull", func() {
session = podmanTest.PodmanNoCache([]string{"pull", imgPath})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
+ session = podmanTest.PodmanNoCache([]string{"images"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.LineInOutputContainsTag(filepath.Join("localhost", dirpath), "latest")).To(BeTrue())
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ })
+
+ It("podman pull from local OCI directory", func() {
+ podmanTest.RestoreArtifact(ALPINE)
+ dirpath := filepath.Join(podmanTest.TempDir, "alpine")
+ os.MkdirAll(dirpath, os.ModePerm)
+ imgPath := fmt.Sprintf("oci:%s", dirpath)
+
+ session := podmanTest.PodmanNoCache([]string{"push", "alpine", imgPath})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ session = podmanTest.PodmanNoCache([]string{"pull", imgPath})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ session = podmanTest.PodmanNoCache([]string{"images"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.LineInOutputContainsTag(filepath.Join("localhost", dirpath), "latest")).To(BeTrue())
session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/run_exit_test.go b/test/e2e/run_exit_test.go
index b05849ddb..861d6b3b7 100644
--- a/test/e2e/run_exit_test.go
+++ b/test/e2e/run_exit_test.go
@@ -41,16 +41,12 @@ var _ = Describe("Podman run exit", func() {
})
It("podman run exit 126", func() {
- SkipIfNotRunc()
-
result := podmanTest.Podman([]string{"run", ALPINE, "/etc"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(126))
})
It("podman run exit 127", func() {
- SkipIfNotRunc()
-
result := podmanTest.Podman([]string{"run", ALPINE, "foobar"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(127))
diff --git a/test/e2e/run_selinux_test.go b/test/e2e/run_selinux_test.go
index a2228411e..dfe71531a 100644
--- a/test/e2e/run_selinux_test.go
+++ b/test/e2e/run_selinux_test.go
@@ -153,4 +153,16 @@ var _ = Describe("Podman run", func() {
Expect(match).Should(BeTrue())
})
+ It("podman run selinux file type setup test", func() {
+ session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "label=type:spc_t", "--security-opt", "label=filetype:container_var_lib_t", fedoraMinimal, "ls", "-Z", "/dev"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ match, _ := session.GrepString("container_var_lib_t")
+ Expect(match).Should(BeTrue())
+
+ session = podmanTest.Podman([]string{"run", "-it", "--security-opt", "label=type:spc_t", "--security-opt", "label=filetype:foobar", fedoraMinimal, "ls", "-Z", "/dev"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(127))
+ })
+
})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index ce2044a72..6e102cfa5 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -417,7 +417,6 @@ var _ = Describe("Podman run", func() {
It("podman run notify_socket", func() {
SkipIfRemote()
- SkipIfNotRunc()
host := GetHostDistributionInfo()
if host.Distribution != "rhel" && host.Distribution != "centos" && host.Distribution != "fedora" {
@@ -629,7 +628,6 @@ var _ = Describe("Podman run", func() {
})
It("podman run exit code on failure to exec", func() {
- SkipIfNotRunc()
session := podmanTest.Podman([]string{"run", ALPINE, "/etc"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(126))
diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go
index 2dbb9545b..fc1203ed1 100644
--- a/test/e2e/start_test.go
+++ b/test/e2e/start_test.go
@@ -101,8 +101,6 @@ var _ = Describe("Podman start", func() {
})
It("podman failed to start with --rm should delete the container", func() {
- SkipIfNotRunc()
-
session := podmanTest.Podman([]string{"create", "-it", "--rm", ALPINE, "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -116,8 +114,6 @@ var _ = Describe("Podman start", func() {
})
It("podman failed to start without --rm should NOT delete the container", func() {
- SkipIfNotRunc()
-
session := podmanTest.Podman([]string{"create", "-it", ALPINE, "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index 5ef84e9b8..a9d2ed1b7 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -22,12 +22,24 @@ RUN apk add nginx
RUN echo $rand_content > /$rand_filename
EOF
- run_podman build -t build_test --format=docker $tmpdir
+ # The 'apk' command can take a long time to fetch files; bump timeout
+ PODMAN_TIMEOUT=240 run_podman build -t build_test --format=docker $tmpdir
is "$output" ".*STEP 4: COMMIT" "COMMIT seen in log"
run_podman run --rm build_test cat /$rand_filename
is "$output" "$rand_content" "reading generated file in image"
- run_podman rmi build_test
+ run_podman rmi -f build_test
}
+
+function teardown() {
+ # A timeout or other error in 'build' can leave behind stale images
+ # that podman can't even see and which will cascade into subsequent
+ # test failures. Try a last-ditch force-rm in cleanup, ignoring errors.
+ run_podman '?' rm -a -f
+ run_podman '?' rmi -f build_test
+
+ basic_teardown
+}
+
# vim: filetype=sh
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
index 1eb9a6bf2..2730fcf4a 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
@@ -13,11 +13,12 @@ import (
// Valid Label Options
var validOptions = map[string]bool{
- "disable": true,
- "type": true,
- "user": true,
- "role": true,
- "level": true,
+ "disable": true,
+ "type": true,
+ "filetype": true,
+ "user": true,
+ "role": true,
+ "level": true,
}
var ErrIncompatibleLabel = fmt.Errorf("Bad SELinux option z and Z can not be used together")
@@ -51,13 +52,16 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
return "", mountLabel, nil
}
if i := strings.Index(opt, ":"); i == -1 {
- return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type' followed by ':' and a value", opt)
+ return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
}
con := strings.SplitN(opt, ":", 2)
if !validOptions[con[0]] {
- return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type'", con[0])
+ return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
}
+ if con[0] == "filetype" {
+ mcon["type"] = con[1]
+ }
pcon[con[0]] = con[1]
if con[0] == "level" || con[0] == "user" {
mcon[con[0]] = con[1]
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
index d7786c33c..2d4e9f890 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
@@ -18,6 +18,7 @@ import (
"strings"
"sync"
"syscall"
+ "golang.org/x/sys/unix"
)
const (
@@ -392,6 +393,14 @@ func SetExecLabel(label string) error {
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), label)
}
+/*
+SetTaskLabel sets the SELinux label for the current thread, or an error.
+This requires the dyntransition permission.
+*/
+func SetTaskLabel(label string) error {
+ return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()), label)
+}
+
// SetSocketLabel takes a process label and tells the kernel to assign the
// label to the next socket that gets created
func SetSocketLabel(label string) error {
@@ -403,6 +412,11 @@ func SocketLabel() (string, error) {
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()))
}
+// PeerLabel retrieves the label of the client on the other side of a socket
+func PeerLabel(fd uintptr) (string, error) {
+ return unix.GetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERSEC)
+}
+
// SetKeyLabel takes a process label and tells the kernel to assign the
// label to the next kernel keyring that gets created
func SetKeyLabel(label string) error {
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
index 79b005d19..0c2e1cd38 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
@@ -97,6 +97,14 @@ func SetExecLabel(label string) error {
}
/*
+SetTaskLabel sets the SELinux label for the current thread, or an error.
+This requires the dyntransition permission.
+*/
+func SetTaskLabel(label string) error {
+ return nil
+}
+
+/*
SetSocketLabel sets the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error.
*/
@@ -109,6 +117,11 @@ func SocketLabel() (string, error) {
return "", nil
}
+// PeerLabel retrieves the label of the client on the other side of a socket
+func PeerLabel(fd uintptr) (string, error) {
+ return "", nil
+}
+
// SetKeyLabel takes a process label and tells the kernel to assign the
// label to the next kernel keyring that gets created
func SetKeyLabel(label string) error {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index efb7d99da..4b992352c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -75,10 +75,10 @@ github.com/containers/image/storage
github.com/containers/image/copy
github.com/containers/image/docker/reference
github.com/containers/image/docker/tarfile
+github.com/containers/image/oci/layout
github.com/containers/image/tarball
github.com/containers/image/pkg/sysregistriesv2
github.com/containers/image/image
-github.com/containers/image/oci/layout
github.com/containers/image/directory/explicitfilepath
github.com/containers/image/docker/policyconfiguration
github.com/containers/image/pkg/blobinfocache/none
@@ -365,7 +365,7 @@ github.com/opencontainers/runtime-tools/generate/seccomp
github.com/opencontainers/runtime-tools/filepath
github.com/opencontainers/runtime-tools/specerror
github.com/opencontainers/runtime-tools/error
-# github.com/opencontainers/selinux v1.2.2
+# github.com/opencontainers/selinux v1.3.0
github.com/opencontainers/selinux/go-selinux/label
github.com/opencontainers/selinux/go-selinux
# github.com/openshift/imagebuilder v1.1.0