mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
daemon/linux: Set console size on creation
On Linux the daemon was not respecting the HostConfig.ConsoleSize property and relied on cli initializing the tty size after the container was created. This caused a delay between container creation and the tty actually being resized. This is also a small change to the api description, because HostConfig.ConsoleSize is no longer Windows-only. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
1a0587bd76
commit
85a7f5a09a
9 changed files with 92 additions and 13 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
||||
"github.com/containerd/containerd/platforms"
|
||||
|
@ -517,6 +518,11 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
hostConfig.KernelMemory = 0
|
||||
}
|
||||
|
||||
if hostConfig != nil && runtime.GOOS == "linux" && versions.LessThan(version, "1.42") {
|
||||
// ConsoleSize is not respected by Linux daemon before API 1.42
|
||||
hostConfig.ConsoleSize = [2]uint{0, 0}
|
||||
}
|
||||
|
||||
var platform *specs.Platform
|
||||
if versions.GreaterThanOrEqualTo(version, "1.41") {
|
||||
if v := r.Form.Get("platform"); v != "" {
|
||||
|
|
|
@ -955,6 +955,15 @@ definitions:
|
|||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/Mount"
|
||||
ConsoleSize:
|
||||
type: "array"
|
||||
description: |
|
||||
Initial console size, as an `[height, width]` array.
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
items:
|
||||
type: "integer"
|
||||
minimum: 0
|
||||
|
||||
# Applicable to UNIX platforms
|
||||
CapAdd:
|
||||
|
@ -1119,15 +1128,6 @@ definitions:
|
|||
type: "string"
|
||||
description: "Runtime to use with this container."
|
||||
# Applicable to Windows
|
||||
ConsoleSize:
|
||||
type: "array"
|
||||
description: |
|
||||
Initial console size, as an `[height, width]` array. (Windows only)
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
items:
|
||||
type: "integer"
|
||||
minimum: 0
|
||||
Isolation:
|
||||
type: "string"
|
||||
description: |
|
||||
|
|
|
@ -417,6 +417,7 @@ type HostConfig struct {
|
|||
AutoRemove bool // Automatically remove container when it exits
|
||||
VolumeDriver string // Name of the volume driver used to mount volumes
|
||||
VolumesFrom []string // List of volumes to take from other container
|
||||
ConsoleSize [2]uint // Initial console size (height,width)
|
||||
|
||||
// Applicable to UNIX platforms
|
||||
CapAdd strslice.StrSlice // List of kernel capabilities to add to the container
|
||||
|
@ -445,8 +446,7 @@ type HostConfig struct {
|
|||
Runtime string `json:",omitempty"` // Runtime to use with this container
|
||||
|
||||
// Applicable to Windows
|
||||
ConsoleSize [2]uint // Initial console size (height,width)
|
||||
Isolation Isolation // Isolation technology of the container (e.g. default, hyperv)
|
||||
Isolation Isolation // Isolation technology of the container (e.g. default, hyperv)
|
||||
|
||||
// Contains container's resources (cgroups, ulimits)
|
||||
Resources
|
||||
|
|
|
@ -27,11 +27,18 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
|
|||
return response, err
|
||||
}
|
||||
|
||||
clientVersion := cli.ClientVersion()
|
||||
|
||||
// When using API 1.24 and under, the client is responsible for removing the container
|
||||
if hostConfig != nil && versions.LessThan(cli.ClientVersion(), "1.25") {
|
||||
if hostConfig != nil && versions.LessThan(clientVersion, "1.25") {
|
||||
hostConfig.AutoRemove = false
|
||||
}
|
||||
|
||||
// When using API under 1.42, the Linux daemon doesn't respect the ConsoleSize
|
||||
if hostConfig != nil && platform != nil && platform.OS == "linux" && versions.LessThan(clientVersion, "1.42") {
|
||||
hostConfig.ConsoleSize = [2]uint{0, 0}
|
||||
}
|
||||
|
||||
if err := cli.NewVersionError("1.41", "specify container image platform"); platform != nil && err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
|
|
@ -1023,7 +1023,9 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e
|
|||
if c.NoNewPrivileges {
|
||||
opts = append(opts, coci.WithNoNewPrivileges)
|
||||
}
|
||||
|
||||
if c.Config.Tty {
|
||||
opts = append(opts, WithConsoleSize(c))
|
||||
}
|
||||
// Set the masked and readonly paths with regard to the host config options if they are set.
|
||||
if c.HostConfig.MaskedPaths != nil {
|
||||
opts = append(opts, coci.WithMaskedPaths(c.HostConfig.MaskedPaths))
|
||||
|
|
23
daemon/oci_opts.go
Normal file
23
daemon/oci_opts.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
coci "github.com/containerd/containerd/oci"
|
||||
"github.com/docker/docker/container"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// WithConsoleSize sets the initial console size
|
||||
func WithConsoleSize(c *container.Container) coci.SpecOpts {
|
||||
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||
if c.HostConfig.ConsoleSize[0] > 0 || c.HostConfig.ConsoleSize[1] > 0 {
|
||||
s.Process.ConsoleSize = &specs.Box{
|
||||
Height: c.HostConfig.ConsoleSize[0],
|
||||
Width: c.HostConfig.ConsoleSize[1],
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -94,6 +94,9 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||
actually supported. API versions before v1.42 continue to ignore these parameters
|
||||
and default to attaching to all streams. To preserve the pre-v1.42 behavior,
|
||||
set all three query parameters (`?stdin=1,stdout=1,stderr=1`).
|
||||
* `POST /containers/create` on Linux now respects the `HostConfig.ConsoleSize` property.
|
||||
Container is immediately created with the desired terminal size and clients no longer
|
||||
need to set the desired size on their own.
|
||||
|
||||
## v1.41 API changes
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package container // import "github.com/docker/docker/integration/container"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/integration/internal/container"
|
||||
|
@ -183,3 +186,31 @@ func TestPrivilegedHostDevices(t *testing.T) {
|
|||
assert.Check(t, is.Equal(strings.TrimSpace(res.Stdout()), devRootOnlyTest))
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsoleSize(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.42"), "skip test from new feature")
|
||||
|
||||
defer setupTest(t)()
|
||||
client := testEnv.APIClient()
|
||||
ctx := context.Background()
|
||||
|
||||
cID := container.Run(ctx, t, client,
|
||||
container.WithTty(true),
|
||||
container.WithImage("busybox"),
|
||||
container.WithCmd("stty", "size"),
|
||||
container.WithConsoleSize(57, 123),
|
||||
)
|
||||
|
||||
poll.WaitOn(t, container.IsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond))
|
||||
|
||||
out, err := client.ContainerLogs(ctx, cID, types.ContainerLogsOptions{ShowStdout: true})
|
||||
assert.NilError(t, err)
|
||||
defer out.Close()
|
||||
|
||||
var b bytes.Buffer
|
||||
_, err = io.Copy(&b, out)
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.Equal(t, strings.TrimSpace(b.String()), "123 57")
|
||||
}
|
||||
|
|
|
@ -227,3 +227,10 @@ func WithIsolation(isolation containertypes.Isolation) func(*TestContainerConfig
|
|||
c.HostConfig.Isolation = isolation
|
||||
}
|
||||
}
|
||||
|
||||
// WithConsoleSize sets the initial console size of the container
|
||||
func WithConsoleSize(width, height uint) func(*TestContainerConfig) {
|
||||
return func(c *TestContainerConfig) {
|
||||
c.HostConfig.ConsoleSize = [2]uint{height, width}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue