Implement conmon exec

This includes:
	Implement exec -i and fix some typos in description of -i docs
	pass failed runtime status to caller
	Add resize handling for a terminal connection
	Customize exec systemd-cgroup slice
	fix healthcheck
	fix top
	add --detach-keys
	Implement podman-remote exec (jhonce)
	* Cleanup some orphaned code (jhonce)
	adapt remote exec for conmon exec (pehunt)
	Fix healthcheck and exec to match docs
		Introduce two new OCIRuntime errors to more comprehensively describe situations in which the runtime can error
		Use these different errors in branching for exit code in healthcheck and exec
	Set conmon to use new api version

Signed-off-by: Jhon Honce <jhonce@redhat.com>

Signed-off-by: Peter Hunt <pehunt@redhat.com>
This commit is contained in:
Peter Hunt
2019-07-01 13:55:03 -04:00
parent cf9efa90e5
commit a1a79c08b7
32 changed files with 1430 additions and 790 deletions

View File

@ -31,7 +31,8 @@ import (
const (
// name of the directory holding the artifacts
artifactsDir = "artifacts"
artifactsDir = "artifacts"
execDirPermission = 0755
)
// rootFsSize gets the size of the container's root filesystem
@ -132,16 +133,93 @@ func (c *Container) AttachSocketPath() string {
return filepath.Join(c.ociRuntime.socketsDir, c.ID(), "attach")
}
// Get PID file path for a container's exec session
func (c *Container) execPidPath(sessionID string) string {
return filepath.Join(c.state.RunDir, "exec_pid_"+sessionID)
}
// exitFilePath gets the path to the container's exit file
func (c *Container) exitFilePath() string {
return filepath.Join(c.ociRuntime.exitsDir, c.ID())
}
// create a bundle path and associated files for an exec session
func (c *Container) createExecBundle(sessionID string) (err error) {
bundlePath := c.execBundlePath(sessionID)
if createErr := os.MkdirAll(bundlePath, execDirPermission); createErr != nil {
return createErr
}
defer func() {
if err != nil {
if err2 := os.RemoveAll(bundlePath); err != nil {
logrus.Warnf("error removing exec bundle after creation caused another error: %v", err2)
}
}
}()
if err2 := os.MkdirAll(c.execExitFileDir(sessionID), execDirPermission); err2 != nil {
// The directory is allowed to exist
if !os.IsExist(err2) {
err = errors.Wrapf(err2, "error creating OCI runtime exit file path %s", c.execExitFileDir(sessionID))
}
}
return
}
// cleanup an exec session after its done
func (c *Container) cleanupExecBundle(sessionID string) error {
return os.RemoveAll(c.execBundlePath(sessionID))
}
// the path to a containers exec session bundle
func (c *Container) execBundlePath(sessionID string) string {
return filepath.Join(c.bundlePath(), sessionID)
}
// Get PID file path for a container's exec session
func (c *Container) execPidPath(sessionID string) string {
return filepath.Join(c.execBundlePath(sessionID), "exec_pid")
}
// the log path for an exec session
func (c *Container) execLogPath(sessionID string) string {
return filepath.Join(c.execBundlePath(sessionID), "exec_log")
}
// the socket conmon creates for an exec session
func (c *Container) execAttachSocketPath(sessionID string) string {
return filepath.Join(c.ociRuntime.socketsDir, sessionID, "attach")
}
// execExitFileDir gets the path to the container's exit file
func (c *Container) execExitFileDir(sessionID string) string {
return filepath.Join(c.execBundlePath(sessionID), "exit")
}
// execOCILog returns the file path for the exec sessions oci log
func (c *Container) execOCILog(sessionID string) string {
if !c.ociRuntime.supportsJSON {
return ""
}
return filepath.Join(c.execBundlePath(sessionID), "oci-log")
}
// readExecExitCode reads the exit file for an exec session and returns
// the exit code
func (c *Container) readExecExitCode(sessionID string) (int, error) {
exitFile := filepath.Join(c.execExitFileDir(sessionID), c.ID())
chWait := make(chan error)
defer close(chWait)
_, err := WaitForFile(exitFile, chWait, time.Second*5)
if err != nil {
return -1, err
}
ec, err := ioutil.ReadFile(exitFile)
if err != nil {
return -1, err
}
ecInt, err := strconv.Atoi(string(ec))
if err != nil {
return -1, err
}
return ecInt, nil
}
// Wait for the container's exit file to appear.
// When it does, update our state based on it.
func (c *Container) waitForExitFileAndSync() error {
@ -849,8 +927,8 @@ func (c *Container) init(ctx context.Context, retainRetries bool) error {
return err
}
// With the newSpec complete, do an OCI create
if err := c.ociRuntime.createContainer(c, c.config.CgroupParent, nil); err != nil {
// With the spec complete, do an OCI create
if err := c.ociRuntime.createContainer(c, nil); err != nil {
return err
}