Skip to content

Commit 605dc5c

Browse files
karampokCF Garden
authored andcommitted
Set initial console size based on process spec
Signed-off-by: Will Martin <[email protected]> Signed-off-by: Petar Petrov <[email protected]> Signed-off-by: Ed King <[email protected]> Signed-off-by: Roberto Jimenez Sanchez <[email protected]> Signed-off-by: Thomas Godkin <[email protected]>
1 parent 0351df1 commit 605dc5c

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed

libcontainer/container_linux.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
522522
cfg.Rlimits = process.Rlimits
523523
}
524524
cfg.CreateConsole = process.ConsoleSocket != nil
525+
cfg.ConsoleWidth = process.ConsoleWidth
526+
cfg.ConsoleHeight = process.ConsoleHeight
525527
return cfg
526528
}
527529

libcontainer/init_linux.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ type initConfig struct {
6262
ContainerId string `json:"containerid"`
6363
Rlimits []configs.Rlimit `json:"rlimits"`
6464
CreateConsole bool `json:"create_console"`
65+
ConsoleWidth uint16 `json:"console_width"`
66+
ConsoleHeight uint16 `json:"console_height"`
6567
Rootless bool `json:"rootless"`
6668
}
6769

@@ -171,12 +173,25 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error {
171173
// however, that setupUser (specifically fixStdioPermissions) *will* change
172174
// the UID owner of the console to be the user the process will run as (so
173175
// they can actually control their console).
174-
console, slavePath, err := console.NewPty()
176+
177+
pty, slavePath, err := console.NewPty()
175178
if err != nil {
176179
return err
177180
}
181+
182+
if config.ConsoleHeight != 0 && config.ConsoleWidth != 0 {
183+
err = pty.Resize(console.WinSize{
184+
Height: config.ConsoleHeight,
185+
Width: config.ConsoleWidth,
186+
})
187+
188+
if err != nil {
189+
return err
190+
}
191+
}
192+
178193
// After we return from here, we don't need the console anymore.
179-
defer console.Close()
194+
defer pty.Close()
180195

181196
// Mount the console inside our rootfs.
182197
if mount {
@@ -185,7 +200,7 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error {
185200
}
186201
}
187202
// While we can access console.master, using the API is a good idea.
188-
if err := utils.SendFd(socket, console.Name(), console.Fd()); err != nil {
203+
if err := utils.SendFd(socket, pty.Name(), pty.Fd()); err != nil {
189204
return err
190205
}
191206
// Now, dup over all the things.

libcontainer/process.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ type Process struct {
4747
// ExtraFiles specifies additional open files to be inherited by the container
4848
ExtraFiles []*os.File
4949

50+
// Initial sizings for the console
51+
ConsoleWidth uint16
52+
ConsoleHeight uint16
53+
5054
// Capabilities specify the capabilities to keep when executing the process inside the container
5155
// All capabilities not specified will be dropped from the processes capability mask
5256
Capabilities *configs.Capabilities

tests/integration/tty.bats

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,60 @@ function teardown() {
116116
[[ ${lines[0]} =~ 1000 ]]
117117
[[ ${lines[1]} =~ 5 ]]
118118
}
119+
120+
@test "runc exec [tty consolesize]" {
121+
# allow writing to filesystem
122+
sed -i 's/"readonly": true/"readonly": false/' config.json
123+
124+
# run busybox detached
125+
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
126+
[ "$status" -eq 0 ]
127+
128+
# make sure we're running
129+
testcontainer test_busybox running
130+
131+
tty_info_with_consize_size=$( cat <<EOF
132+
{
133+
"terminal": true,
134+
"consoleSize": {
135+
"height": 10,
136+
"width": 110
137+
},
138+
"args": [
139+
"/bin/sh",
140+
"-c",
141+
"/bin/stty -a > /tmp/tty-info"
142+
],
143+
"cwd": "/"
144+
}
145+
EOF
146+
)
147+
148+
# run the exec
149+
runc exec --pid-file pid.txt -d --console-socket $CONSOLE_SOCKET -p <( echo $tty_info_with_consize_size ) test_busybox
150+
[ "$status" -eq 0 ]
151+
152+
# check the pid was generated
153+
[ -e pid.txt ]
154+
155+
#wait user process to finish
156+
timeout 1 tail --pid=$(head -n 1 pid.txt) -f /dev/null
157+
158+
tty_info=$( cat <<EOF
159+
{
160+
"args": [
161+
"/bin/cat",
162+
"/tmp/tty-info"
163+
],
164+
"cwd": "/"
165+
}
166+
EOF
167+
)
168+
169+
# run the exec
170+
runc exec -p <( echo $tty_info ) test_busybox
171+
[ "$status" -eq 0 ]
172+
173+
# test tty width and height against original process.json
174+
[[ ${lines[0]} =~ "rows 10; columns 110" ]]
175+
}

utils_linux.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) {
108108
NoNewPrivileges: &p.NoNewPrivileges,
109109
AppArmorProfile: p.ApparmorProfile,
110110
}
111+
112+
if p.ConsoleSize != nil {
113+
lp.ConsoleWidth = uint16(p.ConsoleSize.Width)
114+
lp.ConsoleHeight = uint16(p.ConsoleSize.Height)
115+
}
116+
111117
if p.Capabilities != nil {
112118
lp.Capabilities = &configs.Capabilities{}
113119
lp.Capabilities.Bounding = p.Capabilities.Bounding

0 commit comments

Comments
 (0)