Skip to content

Commit 350d6bc

Browse files
authored
Merge pull request #4792 from laurazard/alternative-fix-no-socket-notif
cli/plugins: use same pgid + skip signal forwarding when attached to a TTY
2 parents a18dad3 + 508346e commit 350d6bc

File tree

5 files changed

+14
-33
lines changed

5 files changed

+14
-33
lines changed

cli-plugins/manager/manager.go

-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ func PluginRunCommand(dockerCli command.Cli, name string, rootcmd *cobra.Command
233233
cmd.Stdin = os.Stdin
234234
cmd.Stdout = os.Stdout
235235
cmd.Stderr = os.Stderr
236-
configureOSSpecificCommand(cmd)
237236

238237
cmd.Env = os.Environ()
239238
cmd.Env = append(cmd.Env, ReexecEnvvar+"="+os.Args[0])

cli-plugins/manager/manager_unix.go

-14
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,7 @@
22

33
package manager
44

5-
import (
6-
"os/exec"
7-
"syscall"
8-
)
9-
105
var defaultSystemPluginDirs = []string{
116
"/usr/local/lib/docker/cli-plugins", "/usr/local/libexec/docker/cli-plugins",
127
"/usr/lib/docker/cli-plugins", "/usr/libexec/docker/cli-plugins",
138
}
14-
15-
func configureOSSpecificCommand(cmd *exec.Cmd) {
16-
// Spawn the plugin process in a new process group, so that signals are not forwarded by the OS.
17-
// The foreground process group is e.g. sent a SIGINT when Ctrl-C is input to the TTY, but we
18-
// implement our own job control for the plugin.
19-
cmd.SysProcAttr = &syscall.SysProcAttr{
20-
Setpgid: true,
21-
}
22-
}

cli-plugins/manager/manager_windows.go

-5
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,10 @@ package manager
22

33
import (
44
"os"
5-
"os/exec"
65
"path/filepath"
76
)
87

98
var defaultSystemPluginDirs = []string{
109
filepath.Join(os.Getenv("ProgramData"), "Docker", "cli-plugins"),
1110
filepath.Join(os.Getenv("ProgramFiles"), "Docker", "cli-plugins"),
1211
}
13-
14-
func configureOSSpecificCommand(cmd *exec.Cmd) {
15-
// no-op
16-
}

cli-plugins/socket/socket.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,20 @@ import (
1414
const EnvKey = "DOCKER_CLI_PLUGIN_SOCKET"
1515

1616
// SetupConn sets up a Unix socket listener, establishes a goroutine to handle connections
17-
// and update the conn pointer, and returns the environment variable to pass to the plugin.
18-
func SetupConn(conn **net.UnixConn) (string, error) {
17+
// and update the conn pointer, and returns the listener for the socket (which the caller
18+
// is responsible for closing when it's no longer needed).
19+
func SetupConn(conn **net.UnixConn) (*net.UnixListener, error) {
1920
listener, err := listen("docker_cli_" + uuid.Generate().String())
2021
if err != nil {
21-
return "", err
22+
return nil, err
2223
}
2324

2425
accept(listener, conn)
2526

26-
return EnvKey + "=" + listener.Addr().String(), nil
27+
return listener, nil
2728
}
2829

2930
func accept(listener *net.UnixListener, conn **net.UnixConn) {
30-
defer listener.Close()
31-
3231
go func() {
3332
for {
3433
// ignore error here, if we failed to accept a connection,

cmd/docker/docker.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,10 @@ func tryPluginRun(dockerCli command.Cli, cmd *cobra.Command, subcommand string,
223223

224224
// Establish the plugin socket, adding it to the environment under a well-known key if successful.
225225
var conn *net.UnixConn
226-
socketenv, err := socket.SetupConn(&conn)
226+
listener, err := socket.SetupConn(&conn)
227227
if err == nil {
228-
envs = append(envs, socketenv)
228+
envs = append(envs, socket.EnvKey+"="+listener.Addr().String())
229+
defer listener.Close()
229230
}
230231

231232
plugincmd.Env = append(envs, plugincmd.Env...)
@@ -240,16 +241,17 @@ func tryPluginRun(dockerCli command.Cli, cmd *cobra.Command, subcommand string,
240241
// we send a SIGKILL to the plugin process and exit
241242
go func() {
242243
retries := 0
243-
for s := range signals {
244+
for range signals {
245+
if dockerCli.Out().IsTerminal() {
246+
// running attached to a terminal, so the plugin will already
247+
// receive signals due to sharing a pgid with the parent CLI
248+
continue
249+
}
244250
if conn != nil {
245251
if err := conn.Close(); err != nil {
246252
_, _ = fmt.Fprintf(dockerCli.Err(), "failed to signal plugin to close: %v\n", err)
247253
}
248254
conn = nil
249-
} else {
250-
// When the plugin is communicating via socket with the host CLI, we perform job control via the socket.
251-
// However, if the plugin is an old version that is not socket-aware, we need to explicitly forward termination signals.
252-
plugincmd.Process.Signal(s)
253255
}
254256
retries++
255257
if retries >= exitLimit {

0 commit comments

Comments
 (0)