summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile2
-rw-r--r--Makefile2
-rw-r--r--README.md39
-rw-r--r--cmd/podman/generate_kube.go2
-rw-r--r--contrib/cirrus/README.md52
-rw-r--r--libpod/boltdb_state_internal.go4
-rw-r--r--libpod/container_internal.go12
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--libpod/oci.go1
-rw-r--r--test/e2e/systemd_test.go81
-rw-r--r--vendor.conf2
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label.go18
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go13
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go11
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go13
15 files changed, 195 insertions, 59 deletions
diff --git a/Dockerfile b/Dockerfile
index 08af0f851..c227207bd 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.10
+FROM golang:1.11
RUN echo 'deb http://httpredir.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/backports.list
diff --git a/Makefile b/Makefile
index 55f34bcc0..55d5ddae3 100644
--- a/Makefile
+++ b/Makefile
@@ -165,7 +165,7 @@ integration.centos:
DIST=CentOS sh .papr_prepare.sh
shell: libpodimage
- ${CONTAINER_RUNTIME} run --tmpfs -e STORAGE_OPTIONS="--storage-driver=vfs" -e CGROUP_MANAGER=cgroupfs -e TESTFLAGS -e TRAVIS -it --privileged --rm -v ${CURDIR}:/go/src/${PROJECT} ${LIBPOD_IMAGE} sh
+ ${CONTAINER_RUNTIME} run -e STORAGE_OPTIONS="--storage-driver=vfs" -e CGROUP_MANAGER=cgroupfs -e TESTFLAGS -e TRAVIS -it --privileged --rm -v ${CURDIR}:/go/src/${PROJECT} ${LIBPOD_IMAGE} sh
testunit: libpodimage
${CONTAINER_RUNTIME} run -e STORAGE_OPTIONS="--storage-driver=vfs" -e TESTFLAGS -e CGROUP_MANAGER=cgroupfs -e TRAVIS -t --privileged --rm -v ${CURDIR}:/go/src/${PROJECT} ${LIBPOD_IMAGE} make localunit
diff --git a/README.md b/README.md
index 640e298e4..865900c62 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,15 @@
![PODMAN logo](logo/podman-logo-source.svg)
-# libpod - library for running OCI-based containers in Pods
-### Latest Version: 0.12.1
-### Status: Active Development
+# Library and tool for running OCI-based containers in Pods
-### Continuous Integration: [![Build Status](https://api.cirrus-ci.com/github/containers/libpod.svg)](https://cirrus-ci.com/github/containers/libpod)
+Libpod provides a library for applications looking to use the Container Pod concept,
+popularized by Kubernetes. libpod also contains the `podman` tool, for managing
+Pods, Containers, and Container Images.
-## What is the scope of this project?
+* [Latest Version: 0.12.1](https://github.com/containers/libpod/releases/latest)
+* [Continuous Integration:](contrib/cirrus/README.md) [![Build Status](https://api.cirrus-ci.com/github/containers/libpod.svg)](https://cirrus-ci.com/github/containers/libpod/master)
-libpod provides a library for applications looking to use the Container Pod concept popularized by Kubernetes.
-libpod also contains a tool called podman for managing Pods, Containers, and Container Images.
+## Overview and scope
At a high level, the scope of libpod and podman is the following:
@@ -19,11 +19,22 @@ At a high level, the scope of libpod and podman is the following:
* Full management of container lifecycle
* Support for pods to manage groups of containers together
* Resource isolation of containers and pods.
+* Integration with CRI-O to share containers and backend code.
-## What is not in scope for this project?
+## Roadmap
-* Signing and pushing images to various image storages. See [Skopeo](https://github.com/containers/skopeo/).
-* Container Runtimes daemons for working with Kubernetes CRIs. See [CRI-O](https://github.com/kubernetes-sigs/cri-o). We are working to integrate libpod into CRI-O to share containers and backend code with Podman.
+1. Python frontend for Varlink API
+1. Integrate libpod into CRI-O to replace its existing container management backend
+1. Further work on the podman pod command
+1. Further improvements on rootless containers
+1. In-memory locking to replace file locks
+
+## Out of scope
+
+* Signing and pushing images to various image storages.
+ See [Skopeo](https://github.com/containers/skopeo/).
+* Container Runtimes daemons for working with Kubernetes CRIs.
+ See [CRI-O](https://github.com/kubernetes-sigs/cri-o).
## OCI Projects Plans
@@ -68,14 +79,6 @@ Release notes for recent Podman versions
**[Contributing](CONTRIBUTING.md)**
Information about contributing to this project.
-## Current Roadmap
-
-1. Python frontend for Varlink API
-1. Integrate libpod into CRI-O to replace its existing container management backend
-1. Further work on the podman pod command
-1. Further improvements on rootless containers
-1. In-memory locking to replace file locks
-
[spec-hooks]: https://github.com/opencontainers/runtime-spec/blob/v2.0.1/config.md#posix-platform-hooks
## Buildah and Podman relationship
diff --git a/cmd/podman/generate_kube.go b/cmd/podman/generate_kube.go
index de9f701b0..6483ffd72 100644
--- a/cmd/podman/generate_kube.go
+++ b/cmd/podman/generate_kube.go
@@ -88,7 +88,7 @@ func generateKubeYAMLCmd(c *cli.Context) error {
return err
}
- header := `# Generation of Kubenetes YAML is still under development!
+ header := `# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
diff --git a/contrib/cirrus/README.md b/contrib/cirrus/README.md
index 436dc5257..e175479f1 100644
--- a/contrib/cirrus/README.md
+++ b/contrib/cirrus/README.md
@@ -66,6 +66,18 @@ task (pass or fail) is set based on the exit status of the last script to execut
### ``cache_images`` Task
+Modifying the contents of cache-images is done by making changes to
+one or more of the ``./contrib/cirrus/packer/*_setup.sh`` files. Testing
+those changes currently requires adding a temporary commit to a PR that
+updates ``.cirrus.yml``:
+
+* Remove all task sections except ``cache_images_task``.
+* Remove the ``only_if`` condition and ``depends_on`` dependencies
+
+The new image names will be displayed at the end of output, assuming the build
+is successful, at that point the temporary commit may be removed. Finally,
+the new names may be used as ``image_name`` values in ``.cirrus.yml``.
+
***N/B: Steps below are performed by automation***
1. When a PR is merged (``$CIRRUS_BRANCH`` == ``master``), run another
@@ -90,12 +102,6 @@ task (pass or fail) is set based on the exit status of the last script to execut
3. If successful, shut down each VM and create a new GCE Image
named with the base image, and the commit sha of the merge.
-***Note:*** The ``.cirrus.yml`` file must be manually updated with the new
-images names, then the change sent in via a secondary pull-request. This
-ensures that all the ``integration_testing`` tasks can pass with the new images,
-before subjecting all future PRs to them. A workflow to automate this
-process is described in comments at the end of the ``.cirrus.yml`` file.
-
### Base-images
Base-images are VM disk-images specially prepared for executing as GCE VMs.
@@ -120,27 +126,27 @@ as the standard 'cloud-init' services.
To produce new base-images, including an `image-builder-image` (used by
the ``cache_images`` Task) some input parameters are required:
- * ``GCP_PROJECT_ID``: The complete GCP project ID string e.g. foobar-12345
- identifying where the images will be stored.
+* ``GCP_PROJECT_ID``: The complete GCP project ID string e.g. foobar-12345
+ identifying where the images will be stored.
- * ``GOOGLE_APPLICATION_CREDENTIALS``: A *JSON* file containing
- credentials for a GCE service account. This can be [a service
- account](https://cloud.google.com/docs/authentication/production#obtaining_and_providing_service_account_credentials_manually)
- or [end-user
- credentials](https://cloud.google.com/docs/authentication/end-user#creating_your_client_credentials]
+* ``GOOGLE_APPLICATION_CREDENTIALS``: A *JSON* file containing
+ credentials for a GCE service account. This can be [a service
+ account](https://cloud.google.com/docs/authentication/production#obtaining_and_providing_service_account_credentials_manually)
+ or [end-user
+ credentials](https://cloud.google.com/docs/authentication/end-user#creating_your_client_credentials)
- * ``RHEL_IMAGE_FILE`` and ``RHEL_CSUM_FILE`` complete paths
- to a `rhel-server-ec2-*.raw.xz` and it's cooresponding
- checksum file. These must be supplied manually because
- they're not available directly via URL like other images.
+* ``RHEL_IMAGE_FILE`` and ``RHEL_CSUM_FILE`` complete paths
+ to a `rhel-server-ec2-*.raw.xz` and it's cooresponding
+ checksum file. These must be supplied manually because
+ they're not available directly via URL like other images.
- * ``RHSM_COMMAND`` contains the complete string needed to register
- the VM for installing package dependencies. The VM will be de-registered
- upon completion.
+* ``RHSM_COMMAND`` contains the complete string needed to register
+ the VM for installing package dependencies. The VM will be de-registered
+ upon completion.
- * Optionally, CSV's may be specified to ``PACKER_BUILDS``
- to limit the base-images produced. For example,
- ``PACKER_BUILDS=fedora,image-builder-image``.
+* Optionally, CSV's may be specified to ``PACKER_BUILDS``
+ to limit the base-images produced. For example,
+ ``PACKER_BUILDS=fedora,image-builder-image``.
If there is an existing 'image-builder-image' within GCE, it may be utilized
to produce base-images (in addition to cache-images). However it must be
diff --git a/libpod/boltdb_state_internal.go b/libpod/boltdb_state_internal.go
index 0970f4d41..06f8dcb24 100644
--- a/libpod/boltdb_state_internal.go
+++ b/libpod/boltdb_state_internal.go
@@ -565,10 +565,12 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error {
}
// Add container to volume dependencies bucket if container is using a named volume
+ if ctr.runtime.config.VolumePath == "" {
+ return nil
+ }
for _, vol := range ctr.config.Spec.Mounts {
if strings.Contains(vol.Source, ctr.runtime.config.VolumePath) {
volName := strings.Split(vol.Source[len(ctr.runtime.config.VolumePath)+1:], "/")[0]
-
volDB := volBkt.Bucket([]byte(volName))
if volDB == nil {
return errors.Wrapf(ErrNoSuchVolume, "no volume with name %s found in database", volName)
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index f69acb33b..af17d8495 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -18,12 +18,12 @@ import (
"github.com/containers/libpod/pkg/ctime"
"github.com/containers/libpod/pkg/hooks"
"github.com/containers/libpod/pkg/hooks/exec"
- "github.com/containers/libpod/pkg/lookup"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/mount"
+ "github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -1027,7 +1027,7 @@ func (c *Container) writeStringToRundir(destFile, output string) (string, error)
return filepath.Join(c.state.DestinationRunDir, destFile), nil
}
-func (c *Container) addLocalVolumes(ctx context.Context, g *generate.Generator) error {
+func (c *Container) addLocalVolumes(ctx context.Context, g *generate.Generator, execUser *user.ExecUser) error {
var uid, gid int
mountPoint := c.state.Mountpoint
if !c.state.Mounted {
@@ -1053,12 +1053,8 @@ func (c *Container) addLocalVolumes(ctx context.Context, g *generate.Generator)
}
if c.config.User != "" {
- if !c.state.Mounted {
- return errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to translate User field", c.ID())
- }
- execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, nil)
- if err != nil {
- return err
+ if execUser == nil {
+ return errors.Wrapf(ErrInternal, "nil pointer passed to addLocalVolumes for execUser")
}
uid = execUser.Uid
gid = execUser.Gid
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index f9b0592f9..4f2955110 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -236,7 +236,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
// Bind builtin image volumes
if c.config.Rootfs == "" && c.config.ImageVolumes {
- if err := c.addLocalVolumes(ctx, &g); err != nil {
+ if err := c.addLocalVolumes(ctx, &g, execUser); err != nil {
return nil, errors.Wrapf(err, "error mounting image volumes")
}
}
diff --git a/libpod/oci.go b/libpod/oci.go
index 3222f9403..093bfdd35 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -861,6 +861,7 @@ func (r *OCIRuntime) execStopContainer(ctr *Container, timeout uint) error {
// checkpointContainer checkpoints the given container
func (r *OCIRuntime) checkpointContainer(ctr *Container, options ContainerCheckpointOptions) error {
+ label.SetSocketLabel(ctr.ProcessLabel())
// imagePath is used by CRIU to store the actual checkpoint files
imagePath := ctr.CheckpointPath()
// workPath will be used to store dump.log and stats-dump
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
new file mode 100644
index 000000000..ce67bb469
--- /dev/null
+++ b/test/e2e/systemd_test.go
@@ -0,0 +1,81 @@
+package integration
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+
+ . "github.com/containers/libpod/test/utils"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("Podman systemd", func() {
+ var (
+ tempdir string
+ err error
+ podmanTest *PodmanTestIntegration
+ systemd_unit_file string
+ )
+
+ BeforeEach(func() {
+ tempdir, err = CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest = PodmanTestCreate(tempdir)
+ podmanTest.RestoreAllArtifacts()
+ systemd_unit_file = `[Unit]
+Description=redis container
+[Service]
+Restart=always
+ExecStart=/usr/bin/podman start -a redis
+ExecStop=/usr/bin/podman stop -t 10 redis
+KillMode=process
+[Install]
+WantedBy=multi-user.target
+`
+ })
+
+ AfterEach(func() {
+ podmanTest.Cleanup()
+ f := CurrentGinkgoTestDescription()
+ timedResult := fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds())
+ GinkgoWriter.Write([]byte(timedResult))
+ })
+
+ It("podman start container by systemd", func() {
+ if os.Getenv("SKIP_USERNS") != "" {
+ Skip("Skip userns tests.")
+ }
+
+ sys_file := ioutil.WriteFile("/etc/systemd/system/redis.service", []byte(systemd_unit_file), 0644)
+ Expect(sys_file).To(BeNil())
+
+ create := podmanTest.Podman([]string{"create", "-d", "--name", "redis", "redis"})
+ create.WaitWithDefaultTimeout()
+ Expect(create.ExitCode()).To(Equal(0))
+
+ enable := SystemExec("bash", []string{"-c", "systemctl daemon-reload && systemctl enable --now redis"})
+ enable.WaitWithDefaultTimeout()
+ Expect(enable.ExitCode()).To(Equal(0))
+
+ start := SystemExec("bash", []string{"-c", "systemctl start redis"})
+ start.WaitWithDefaultTimeout()
+
+ logs := SystemExec("bash", []string{"-c", "journalctl -n 20 -u redis"})
+ logs.WaitWithDefaultTimeout()
+
+ status := SystemExec("bash", []string{"-c", "systemctl status redis"})
+ status.WaitWithDefaultTimeout()
+ Expect(status.OutputToString()).To(ContainSubstring("active (running)"))
+
+ cleanup := SystemExec("bash", []string{"-c", "systemctl stop redis && systemctl disable redis"})
+ cleanup.WaitWithDefaultTimeout()
+ Expect(cleanup.ExitCode()).To(Equal(0))
+ os.Remove("/etc/systemd/system/redis.service")
+ sys_clean := SystemExec("bash", []string{"-c", "systemctl daemon-reload"})
+ sys_clean.WaitWithDefaultTimeout()
+ Expect(sys_clean.ExitCode()).To(Equal(0))
+ })
+})
diff --git a/vendor.conf b/vendor.conf
index 75483e9f3..f2d7fa414 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -51,7 +51,7 @@ github.com/opencontainers/image-spec v1.0.0
github.com/opencontainers/runc b4e2ecb452d9ee4381137cc0a7e6715b96bed6de
github.com/opencontainers/runtime-spec d810dbc60d8c5aeeb3d054bd1132fab2121968ce
github.com/opencontainers/runtime-tools master
-github.com/opencontainers/selinux 6ba084dd09db3dfe49a839bab0bbe97fd9274d80
+github.com/opencontainers/selinux 51c6c0a5dbc675792e953298cb9871819d6f9bb8
github.com/ostreedev/ostree-go master
github.com/pkg/errors v0.8.0
github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
index 2a31cd3c5..bb27ac936 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
@@ -9,7 +9,7 @@ func InitLabels(options []string) (string, string, error) {
return "", "", nil
}
-func GetROMountLabel() string {
+func ROMountLabel() string {
return ""
}
@@ -25,7 +25,19 @@ func SetProcessLabel(processLabel string) error {
return nil
}
-func GetFileLabel(path string) (string, error) {
+func ProcessLabel() (string, error) {
+ return "", nil
+}
+
+func SetSocketLabel(processLabel string) error {
+ return nil
+}
+
+func SocketLabel() (string, error) {
+ return "", nil
+}
+
+func FileLabel(path string) (string, error) {
return "", nil
}
@@ -41,7 +53,7 @@ func Relabel(path string, fileLabel string, shared bool) error {
return nil
}
-func GetPidLabel(pid int) (string, error) {
+func PidLabel(pid int) (string, error) {
return "", nil
}
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 63c4edd05..de214b2d5 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
@@ -95,6 +95,17 @@ func SetProcessLabel(processLabel string) error {
return selinux.SetExecLabel(processLabel)
}
+// SetSocketLabel takes a process label and tells the kernel to assign the
+// label to the next socket that gets created
+func SetSocketLabel(processLabel string) error {
+ return selinux.SetSocketLabel(processLabel)
+}
+
+// SocketLabel retrieves the current default socket label setting
+func SocketLabel() (string, error) {
+ return selinux.SocketLabel()
+}
+
// ProcessLabel returns the process label that the kernel will assign
// to the next program executed by the current process. If "" is returned
// this indicates that the default labeling will happen for the process.
@@ -102,7 +113,7 @@ func ProcessLabel() (string, error) {
return selinux.ExecLabel()
}
-// GetFileLabel returns the label for specified path
+// FileLabel returns the label for specified path
func FileLabel(path string) (string, error) {
return selinux.FileLabel(path)
}
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 bbaa1e0d7..7832f7497 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
@@ -385,6 +385,17 @@ func SetExecLabel(label string) error {
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", 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 {
+ return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()), label)
+}
+
+// SocketLabel retrieves the current socket label setting
+func SocketLabel() (string, error) {
+ return readCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()))
+}
+
// Get returns the Context as a string
func (c Context) Get() string {
if c["level"] != "" {
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 5abf8a362..99efa155a 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
@@ -96,6 +96,19 @@ func SetExecLabel(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.
+*/
+func SetSocketLabel(label string) error {
+ return nil
+}
+
+// SocketLabel retrieves the current socket label setting
+func SocketLabel() (string, error) {
+ return "", nil
+}
+
// Get returns the Context as a string
func (c Context) Get() string {
return ""