merge branch 'pr-1275'
Set initial console size based on process spec LGTMs: @crosbymichael @cyphar Closes #1275
This commit is contained in:
commit
dc1552a6f3
|
@ -522,6 +522,8 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
|
||||||
cfg.Rlimits = process.Rlimits
|
cfg.Rlimits = process.Rlimits
|
||||||
}
|
}
|
||||||
cfg.CreateConsole = process.ConsoleSocket != nil
|
cfg.CreateConsole = process.ConsoleSocket != nil
|
||||||
|
cfg.ConsoleWidth = process.ConsoleWidth
|
||||||
|
cfg.ConsoleHeight = process.ConsoleHeight
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,8 @@ type initConfig struct {
|
||||||
ContainerId string `json:"containerid"`
|
ContainerId string `json:"containerid"`
|
||||||
Rlimits []configs.Rlimit `json:"rlimits"`
|
Rlimits []configs.Rlimit `json:"rlimits"`
|
||||||
CreateConsole bool `json:"create_console"`
|
CreateConsole bool `json:"create_console"`
|
||||||
|
ConsoleWidth uint16 `json:"console_width"`
|
||||||
|
ConsoleHeight uint16 `json:"console_height"`
|
||||||
Rootless bool `json:"rootless"`
|
Rootless bool `json:"rootless"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,12 +173,25 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error {
|
||||||
// however, that setupUser (specifically fixStdioPermissions) *will* change
|
// however, that setupUser (specifically fixStdioPermissions) *will* change
|
||||||
// the UID owner of the console to be the user the process will run as (so
|
// the UID owner of the console to be the user the process will run as (so
|
||||||
// they can actually control their console).
|
// they can actually control their console).
|
||||||
console, slavePath, err := console.NewPty()
|
|
||||||
|
pty, slavePath, err := console.NewPty()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.ConsoleHeight != 0 && config.ConsoleWidth != 0 {
|
||||||
|
err = pty.Resize(console.WinSize{
|
||||||
|
Height: config.ConsoleHeight,
|
||||||
|
Width: config.ConsoleWidth,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// After we return from here, we don't need the console anymore.
|
// After we return from here, we don't need the console anymore.
|
||||||
defer console.Close()
|
defer pty.Close()
|
||||||
|
|
||||||
// Mount the console inside our rootfs.
|
// Mount the console inside our rootfs.
|
||||||
if mount {
|
if mount {
|
||||||
|
@ -185,7 +200,7 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// While we can access console.master, using the API is a good idea.
|
// While we can access console.master, using the API is a good idea.
|
||||||
if err := utils.SendFd(socket, console.Name(), console.Fd()); err != nil {
|
if err := utils.SendFd(socket, pty.Name(), pty.Fd()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Now, dup over all the things.
|
// Now, dup over all the things.
|
||||||
|
|
|
@ -47,6 +47,10 @@ type Process struct {
|
||||||
// ExtraFiles specifies additional open files to be inherited by the container
|
// ExtraFiles specifies additional open files to be inherited by the container
|
||||||
ExtraFiles []*os.File
|
ExtraFiles []*os.File
|
||||||
|
|
||||||
|
// Initial sizings for the console
|
||||||
|
ConsoleWidth uint16
|
||||||
|
ConsoleHeight uint16
|
||||||
|
|
||||||
// Capabilities specify the capabilities to keep when executing the process inside the container
|
// Capabilities specify the capabilities to keep when executing the process inside the container
|
||||||
// All capabilities not specified will be dropped from the processes capability mask
|
// All capabilities not specified will be dropped from the processes capability mask
|
||||||
Capabilities *configs.Capabilities
|
Capabilities *configs.Capabilities
|
||||||
|
|
|
@ -116,3 +116,60 @@ function teardown() {
|
||||||
[[ ${lines[0]} =~ 1000 ]]
|
[[ ${lines[0]} =~ 1000 ]]
|
||||||
[[ ${lines[1]} =~ 5 ]]
|
[[ ${lines[1]} =~ 5 ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "runc exec [tty consolesize]" {
|
||||||
|
# allow writing to filesystem
|
||||||
|
sed -i 's/"readonly": true/"readonly": false/' config.json
|
||||||
|
|
||||||
|
# run busybox detached
|
||||||
|
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
# make sure we're running
|
||||||
|
testcontainer test_busybox running
|
||||||
|
|
||||||
|
tty_info_with_consize_size=$( cat <<EOF
|
||||||
|
{
|
||||||
|
"terminal": true,
|
||||||
|
"consoleSize": {
|
||||||
|
"height": 10,
|
||||||
|
"width": 110
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"/bin/sh",
|
||||||
|
"-c",
|
||||||
|
"/bin/stty -a > /tmp/tty-info"
|
||||||
|
],
|
||||||
|
"cwd": "/"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# run the exec
|
||||||
|
runc exec --pid-file pid.txt -d --console-socket $CONSOLE_SOCKET -p <( echo $tty_info_with_consize_size ) test_busybox
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
# check the pid was generated
|
||||||
|
[ -e pid.txt ]
|
||||||
|
|
||||||
|
#wait user process to finish
|
||||||
|
timeout 1 tail --pid=$(head -n 1 pid.txt) -f /dev/null
|
||||||
|
|
||||||
|
tty_info=$( cat <<EOF
|
||||||
|
{
|
||||||
|
"args": [
|
||||||
|
"/bin/cat",
|
||||||
|
"/tmp/tty-info"
|
||||||
|
],
|
||||||
|
"cwd": "/"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# run the exec
|
||||||
|
runc exec -p <( echo $tty_info ) test_busybox
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
# test tty width and height against original process.json
|
||||||
|
[[ ${lines[0]} =~ "rows 10; columns 110" ]]
|
||||||
|
}
|
||||||
|
|
|
@ -108,6 +108,12 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) {
|
||||||
NoNewPrivileges: &p.NoNewPrivileges,
|
NoNewPrivileges: &p.NoNewPrivileges,
|
||||||
AppArmorProfile: p.ApparmorProfile,
|
AppArmorProfile: p.ApparmorProfile,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.ConsoleSize != nil {
|
||||||
|
lp.ConsoleWidth = uint16(p.ConsoleSize.Width)
|
||||||
|
lp.ConsoleHeight = uint16(p.ConsoleSize.Height)
|
||||||
|
}
|
||||||
|
|
||||||
if p.Capabilities != nil {
|
if p.Capabilities != nil {
|
||||||
lp.Capabilities = &configs.Capabilities{}
|
lp.Capabilities = &configs.Capabilities{}
|
||||||
lp.Capabilities.Bounding = p.Capabilities.Bounding
|
lp.Capabilities.Bounding = p.Capabilities.Bounding
|
||||||
|
|
Loading…
Reference in New Issue