summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAPI.md2
-rw-r--r--cmd/podman/commit.go4
-rw-r--r--cmd/podman/varlink/io.projectatomic.podman.varlink2
-rw-r--r--contrib/python/podman/libs/__init__.py6
-rw-r--r--contrib/python/podman/libs/_containers_attach.py111
-rw-r--r--contrib/python/podman/libs/containers.py10
-rw-r--r--contrib/python/test/podman_testcase.py3
-rw-r--r--contrib/python/test/test_containers.py20
-rw-r--r--docs/podman-commit.1.md4
-rw-r--r--libpod/container_commit.go5
-rw-r--r--libpod/runtime.go1
-rw-r--r--vendor.conf2
-rw-r--r--vendor/github.com/projectatomic/buildah/commit.go3
-rw-r--r--vendor/github.com/projectatomic/buildah/config.go22
-rw-r--r--vendor/github.com/projectatomic/buildah/imagebuildah/build.go8
-rw-r--r--vendor/github.com/projectatomic/buildah/imagebuildah/chroot_symlink.go2
-rw-r--r--vendor/github.com/projectatomic/buildah/pkg/cli/common.go4
17 files changed, 185 insertions, 24 deletions
diff --git a/API.md b/API.md
index 0f4a1e55b..b6e2f9be1 100755
--- a/API.md
+++ b/API.md
@@ -159,7 +159,7 @@ method Commit(name: [string](https://godoc.org/builtin#string), image_name: [str
Commit, creates an image from an existing container. It requires the name or
ID of the container as well as the resulting image name. Optionally, you can define an author and message
to be added to the resulting image. You can also define changes to the resulting image for the following
-attributes: _CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, STOPSIGNAL, USER, VOLUME, and WORKDIR_. To pause the
+attributes: _CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, ONBUILD, STOPSIGNAL, USER, VOLUME, and WORKDIR_. To pause the
container while it is being committed, pass a _true_ bool for the pause argument. If the container cannot
be found by the ID or name provided, a (ContainerNotFound)[#ContainerNotFound] error will be returned; otherwise,
the resulting image's ID will be returned as a string.
diff --git a/cmd/podman/commit.go b/cmd/podman/commit.go
index ce8e99dd4..90a003e8e 100644
--- a/cmd/podman/commit.go
+++ b/cmd/podman/commit.go
@@ -19,7 +19,7 @@ var (
commitFlags = []cli.Flag{
cli.StringSliceFlag{
Name: "change, c",
- Usage: "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR",
+ Usage: fmt.Sprintf("Apply the following possible instructions to the created image (default []): %s", strings.Join(libpod.ChangeCmds, " | ")),
},
cli.StringFlag{
Name: "format, f",
@@ -92,7 +92,7 @@ func commitCmd(c *cli.Context) error {
if c.IsSet("change") {
for _, change := range c.StringSlice("change") {
splitChange := strings.Split(strings.ToUpper(change), "=")
- if !util.StringInSlice(splitChange[0], []string{"CMD", "ENTRYPOINT", "ENV", "EXPOSE", "LABEL", "STOPSIGNAL", "USER", "VOLUME", "WORKDIR"}) {
+ if !util.StringInSlice(splitChange[0], libpod.ChangeCmds) {
return errors.Errorf("invalid syntax for --change ", change)
}
}
diff --git a/cmd/podman/varlink/io.projectatomic.podman.varlink b/cmd/podman/varlink/io.projectatomic.podman.varlink
index 90139f732..0066e6fb2 100644
--- a/cmd/podman/varlink/io.projectatomic.podman.varlink
+++ b/cmd/podman/varlink/io.projectatomic.podman.varlink
@@ -575,7 +575,7 @@ method DeleteUnusedImages() -> (images: []string)
# Commit, creates an image from an existing container. It requires the name or
# ID of the container as well as the resulting image name. Optionally, you can define an author and message
# to be added to the resulting image. You can also define changes to the resulting image for the following
-# attributes: _CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, STOPSIGNAL, USER, VOLUME, and WORKDIR_. To pause the
+# attributes: _CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, ONBUILD, STOPSIGNAL, USER, VOLUME, and WORKDIR_. To pause the
# container while it is being committed, pass a _true_ bool for the pause argument. If the container cannot
# be found by the ID or name provided, a (ContainerNotFound)[#ContainerNotFound] error will be returned; otherwise,
# the resulting image's ID will be returned as a string.
diff --git a/contrib/python/podman/libs/__init__.py b/contrib/python/podman/libs/__init__.py
index 9db5dacf5..3a8a35021 100644
--- a/contrib/python/podman/libs/__init__.py
+++ b/contrib/python/podman/libs/__init__.py
@@ -1,4 +1,5 @@
"""Support files for podman API implementation."""
+import collections
import datetime
import functools
@@ -12,12 +13,11 @@ __all__ = [
def cached_property(fn):
- """Cache return to save future expense."""
+ """Decorate property to cache return value."""
return property(functools.lru_cache(maxsize=8)(fn))
-# Cannot subclass collections.UserDict, breaks varlink
-class Config(dict):
+class Config(collections.UserDict):
"""Silently ignore None values, only take key once."""
def __init__(self, **kwargs):
diff --git a/contrib/python/podman/libs/_containers_attach.py b/contrib/python/podman/libs/_containers_attach.py
new file mode 100644
index 000000000..54e6a009e
--- /dev/null
+++ b/contrib/python/podman/libs/_containers_attach.py
@@ -0,0 +1,111 @@
+"""Exported method Container.attach()."""
+
+import fcntl
+import os
+import select
+import signal
+import socket
+import struct
+import sys
+import termios
+import tty
+
+CONMON_BUFSZ = 8192
+
+
+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.
+ """
+ if stdin is None:
+ stdin = sys.stdin.fileno()
+
+ if stdout is None:
+ stdout = sys.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
+ ctl_socket = attach['sockets']['control_socket']
+
+ def resize_handler(signum, frame):
+ """Send the new window size to conmon.
+
+ The method arguments are not used.
+ """
+ packed = fcntl.ioctl(stdout, termios.TIOCGWINSZ,
+ struct.pack('HHHH', 0, 0, 0, 0))
+ rows, cols, _, _ = struct.unpack('HHHH', packed)
+
+ with open(ctl_socket, 'w') as skt:
+ # send conmon window resize message
+ skt.write('1 {} {}\n'.format(rows, cols))
+
+ def log_handler(signum, frame):
+ """Send command to reopen log to conmon.
+
+ The method arguments are not used.
+ """
+ with open(ctl_socket, 'w') as skt:
+ # send conmon reopen log message
+ skt.write('2\n')
+
+ try:
+ # save off the old settings for terminal
+ original_attr = termios.tcgetattr(stdout)
+ tty.setraw(stdin)
+
+ # initialize containers window size
+ resize_handler(None, sys._getframe(0))
+
+ # catch any resizing events and send the resize info
+ # to the control fifo "socket"
+ signal.signal(signal.SIGWINCH, resize_handler)
+ except termios.error:
+ original_attr = None
+
+ try:
+ # Prepare socket for communicating with conmon/container
+ with socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) as skt:
+ skt.connect(io_socket)
+ skt.sendall(b'\n')
+
+ sources = [skt, stdin]
+ while sources:
+ readable, _, _ = select.select(sources, [], [])
+ for r in readable:
+ if r is skt:
+ data = r.recv(CONMON_BUFSZ)
+ if not data:
+ sources.remove(skt)
+
+ # Remove source marker when writing
+ os.write(stdout, data[1:])
+ elif r is stdin:
+ data = os.read(stdin, CONMON_BUFSZ)
+ if not data:
+ sources.remove(stdin)
+
+ skt.sendall(data)
+
+ if eot in data:
+ sources.clear()
+ break
+ else:
+ raise ValueError('Unknown source in select')
+ finally:
+ if original_attr:
+ termios.tcsetattr(stdout, termios.TCSADRAIN, original_attr)
+ signal.signal(signal.SIGWINCH, signal.SIG_DFL)
diff --git a/contrib/python/podman/libs/containers.py b/contrib/python/podman/libs/containers.py
index 96ec6be37..a350a128a 100644
--- a/contrib/python/podman/libs/containers.py
+++ b/contrib/python/podman/libs/containers.py
@@ -6,8 +6,10 @@ import json
import signal
import time
+from ._containers_attach import Mixin as AttachMixin
-class Container(collections.UserDict):
+
+class Container(collections.UserDict, AttachMixin):
"""Model for a container."""
def __init__(self, client, id, data):
@@ -46,12 +48,6 @@ class Container(collections.UserDict):
with self._client() as podman:
return self._refresh(podman)
- def attach(self, detach_key=None, no_stdin=False, sig_proxy=True):
- """Attach to running container."""
- with self._client() as podman:
- # TODO: streaming and port magic occur, need arguments
- podman.AttachToContainer()
-
def processes(self):
"""Show processes running in container."""
with self._client() as podman:
diff --git a/contrib/python/test/podman_testcase.py b/contrib/python/test/podman_testcase.py
index fc99f26ce..f96a3a013 100644
--- a/contrib/python/test/podman_testcase.py
+++ b/contrib/python/test/podman_testcase.py
@@ -62,7 +62,8 @@ class PodmanTestCase(unittest.TestCase):
cmd = ['podman']
cmd.extend(podman_args)
- cmd.extend(['run', '-d', 'alpine', 'sleep', '500'])
+ # cmd.extend(['run', '-d', 'alpine', 'sleep', '500'])
+ cmd.extend(['run', '-dt', 'alpine', '/bin/sh'])
PodmanTestCase.alpine_process = subprocess.Popen(
cmd,
stdout=PodmanTestCase.alpine_log,
diff --git a/contrib/python/test/test_containers.py b/contrib/python/test/test_containers.py
index 5c7c9934b..87d43adb4 100644
--- a/contrib/python/test/test_containers.py
+++ b/contrib/python/test/test_containers.py
@@ -1,11 +1,9 @@
import os
import signal
-import time
import unittest
from test.podman_testcase import PodmanTestCase
import podman
-from podman import datetime_parse
class TestContainers(PodmanTestCase):
@@ -65,8 +63,22 @@ class TestContainers(PodmanTestCase):
self.pclient.containers.get("bozo")
def test_attach(self):
- with self.assertRaisesNotImplemented():
- self.alpine_ctnr.attach()
+ # 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)
+
+ self.alpine_ctnr.attach(
+ stdin=mock_in.fileno(), stdout=mock_out.fileno())
+
+ mock_out.flush()
+ mock_out.seek(0, 0)
+ output = mock_out.read()
+ self.assertIn('Hello', output)
def test_processes(self):
actual = list(self.alpine_ctnr.processes())
diff --git a/docs/podman-commit.1.md b/docs/podman-commit.1.md
index 1ae83f10e..6416a4c69 100644
--- a/docs/podman-commit.1.md
+++ b/docs/podman-commit.1.md
@@ -24,7 +24,9 @@ Set the author for the committed image
**--change, -c**
Apply the following possible instructions to the created image:
-**CMD** | **ENTRYPOINT** | **ENV** | **EXPOSE** | **LABEL** | **STOPSIGNAL** | **USER** | **VOLUME** | **WORKDIR**
+**CMD** | **ENTRYPOINT** | **ENV** | **EXPOSE** | **LABEL** | **ONBUILD** | **STOPSIGNAL** | **USER** | **VOLUME** | **WORKDIR**
+
+
Can be set multiple times
**--format, -f**
diff --git a/libpod/container_commit.go b/libpod/container_commit.go
index 8cb04ec1a..2872012b8 100644
--- a/libpod/container_commit.go
+++ b/libpod/container_commit.go
@@ -24,6 +24,9 @@ type ContainerCommitOptions struct {
Changes []string
}
+// ChangeCmds is the list of valid Changes commands to passed to the Commit call
+var ChangeCmds = []string{"CMD", "ENTRYPOINT", "ENV", "EXPOSE", "LABEL", "ONBUILD", "STOPSIGNAL", "USER", "VOLUME", "WORKDIR"}
+
// Commit commits the changes between a container and its image, creating a new
// image
func (c *Container) Commit(ctx context.Context, destImage string, options ContainerCommitOptions) (*image.Image, error) {
@@ -138,6 +141,8 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
isLabelCleared = true
}
importBuilder.SetLabel(splitChange[1], splitChange[2])
+ case "ONBUILD":
+ importBuilder.SetOnBuild(splitChange[1])
case "STOPSIGNAL":
// No Set StopSignal
case "USER":
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 52a2653b3..b208bc718 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -151,6 +151,7 @@ var (
"/usr/lib/cri-o-runc/sbin/runc",
},
ConmonPath: []string{
+ "/usr/libexec/podman/conmon",
"/usr/libexec/crio/conmon",
"/usr/local/libexec/crio/conmon",
"/usr/bin/conmon",
diff --git a/vendor.conf b/vendor.conf
index 6f20bc1e5..e53d04523 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -88,7 +88,7 @@ k8s.io/kube-openapi 275e2ce91dec4c05a4094a7b1daee5560b555ac9 https://github.com/
k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e https://github.com/kubernetes/utils
github.com/mrunalp/fileutils master
github.com/varlink/go master
-github.com/projectatomic/buildah 25f4e8ec639044bff4ab393188d083782f07b61c
+github.com/projectatomic/buildah b66e8531456e2986ffc409f591c9005813589a34
github.com/Nvveen/Gotty master
github.com/fsouza/go-dockerclient master
github.com/openshift/imagebuilder master
diff --git a/vendor/github.com/projectatomic/buildah/commit.go b/vendor/github.com/projectatomic/buildah/commit.go
index 75d2626f5..ab46a0643 100644
--- a/vendor/github.com/projectatomic/buildah/commit.go
+++ b/vendor/github.com/projectatomic/buildah/commit.go
@@ -52,6 +52,9 @@ type CommitOptions struct {
// Squash tells the builder to produce an image with a single layer
// instead of with possibly more than one layer.
Squash bool
+
+ // OnBuild is a list of commands to be run by images based on this image
+ OnBuild []string
}
// PushOptions can be used to alter how an image is copied somewhere.
diff --git a/vendor/github.com/projectatomic/buildah/config.go b/vendor/github.com/projectatomic/buildah/config.go
index c5fabdec6..3d67895da 100644
--- a/vendor/github.com/projectatomic/buildah/config.go
+++ b/vendor/github.com/projectatomic/buildah/config.go
@@ -331,6 +331,24 @@ func (b *Builder) SetUser(spec string) {
b.Docker.Config.User = spec
}
+// OnBuild returns the OnBuild value from the container.
+func (b *Builder) OnBuild() []string {
+ return copyStringSlice(b.Docker.Config.OnBuild)
+}
+
+// ClearOnBuild removes all values from the OnBuild structure
+func (b *Builder) ClearOnBuild() {
+ b.Docker.Config.OnBuild = []string{}
+}
+
+// SetOnBuild sets a trigger instruction to be executed when the image is used
+// as the base of another image.
+// Note: this setting is not present in the OCIv1 image format, so it is
+// discarded when writing images using OCIv1 formats.
+func (b *Builder) SetOnBuild(onBuild string) {
+ b.Docker.Config.OnBuild = append(b.Docker.Config.OnBuild, onBuild)
+}
+
// WorkDir returns the default working directory for running commands in the
// container, or in a container built using an image built from this container.
func (b *Builder) WorkDir() string {
@@ -348,7 +366,7 @@ func (b *Builder) SetWorkDir(there string) {
// Shell returns the default shell for running commands in the
// container, or in a container built using an image built from this container.
func (b *Builder) Shell() []string {
- return b.Docker.Config.Shell
+ return copyStringSlice(b.Docker.Config.Shell)
}
// SetShell sets the default shell for running
@@ -357,7 +375,7 @@ func (b *Builder) Shell() []string {
// Note: this setting is not present in the OCIv1 image format, so it is
// discarded when writing images using OCIv1 formats.
func (b *Builder) SetShell(shell []string) {
- b.Docker.Config.Shell = shell
+ b.Docker.Config.Shell = copyStringSlice(shell)
}
// Env returns a list of key-value pairs to be set when running commands in the
diff --git a/vendor/github.com/projectatomic/buildah/imagebuildah/build.go b/vendor/github.com/projectatomic/buildah/imagebuildah/build.go
index a2e2912e3..f3d28510a 100644
--- a/vendor/github.com/projectatomic/buildah/imagebuildah/build.go
+++ b/vendor/github.com/projectatomic/buildah/imagebuildah/build.go
@@ -138,6 +138,8 @@ type BuildOptions struct {
Labels []string
// Annotation metadata for an image
Annotations []string
+ // OnBuild commands to be run by images based on this image
+ OnBuild []string
}
// Executor is a buildah-based implementation of the imagebuilder.Executor
@@ -183,6 +185,7 @@ type Executor struct {
squash bool
labels []string
annotations []string
+ onbuild []string
}
// withName creates a new child executor that will be used whenever a COPY statement uses --from=NAME.
@@ -598,6 +601,7 @@ func (b *Executor) Prepare(ctx context.Context, ib *imagebuilder.Builder, node *
Labels: builder.Labels(),
Shell: builder.Shell(),
StopSignal: builder.StopSignal(),
+ OnBuild: builder.OnBuild(),
}
var rootfs *docker.RootFS
if builder.Docker.RootFS != nil {
@@ -714,6 +718,10 @@ func (b *Executor) Commit(ctx context.Context, ib *imagebuilder.Builder) (err er
for v := range config.Volumes {
b.builder.AddVolume(v)
}
+ b.builder.ClearOnBuild()
+ for _, onBuildSpec := range config.OnBuild {
+ b.builder.SetOnBuild(onBuildSpec)
+ }
b.builder.SetWorkDir(config.WorkingDir)
b.builder.SetEntrypoint(config.Entrypoint)
b.builder.SetShell(config.Shell)
diff --git a/vendor/github.com/projectatomic/buildah/imagebuildah/chroot_symlink.go b/vendor/github.com/projectatomic/buildah/imagebuildah/chroot_symlink.go
index b2452b61c..f1fec7f70 100644
--- a/vendor/github.com/projectatomic/buildah/imagebuildah/chroot_symlink.go
+++ b/vendor/github.com/projectatomic/buildah/imagebuildah/chroot_symlink.go
@@ -37,7 +37,7 @@ func resolveChrootedSymlinks() {
os.Exit(1)
}
- // Our second paramter is the path name to evaluate for symbolic links
+ // Our second parameter is the path name to evaluate for symbolic links
symLink, err := getSymbolicLink(flag.Arg(0), flag.Arg(1))
if err != nil {
fmt.Fprintf(os.Stderr, "error getting symbolic links: %v\n", err)
diff --git a/vendor/github.com/projectatomic/buildah/pkg/cli/common.go b/vendor/github.com/projectatomic/buildah/pkg/cli/common.go
index e4a30a315..a7b61d561 100644
--- a/vendor/github.com/projectatomic/buildah/pkg/cli/common.go
+++ b/vendor/github.com/projectatomic/buildah/pkg/cli/common.go
@@ -152,6 +152,10 @@ var (
Name: "squash",
Usage: "Squash newly built layers into a single new layer. Buildah does not currently support caching so this is a NOOP.",
},
+ cli.BoolTFlag{
+ Name: "stream",
+ Usage: "There is no daemon in use, so this command is a NOOP.",
+ },
cli.StringSliceFlag{
Name: "tag, t",
Usage: "tagged `name` to apply to the built image",