Skip to content

Commit 9fbee9a

Browse files
Merge pull request #586 from joshbranham/console-container-cleanup
OSD-27228: Ensure containers are cleaned up when SIGINT is called
2 parents 50b26a4 + a272694 commit 9fbee9a

File tree

4 files changed

+124
-180
lines changed

4 files changed

+124
-180
lines changed

cmd/ocm-backplane/console/console.go

+41-69
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import (
3333
"time"
3434

3535
"github.com/Masterminds/semver"
36-
homedir "github.com/mitchellh/go-homedir"
36+
"github.com/mitchellh/go-homedir"
3737
consolev1typedclient "github.com/openshift/client-go/console/clientset/versioned/typed/console/v1"
3838
consolev1alpha1typedclient "github.com/openshift/client-go/console/clientset/versioned/typed/console/v1alpha1"
3939
operatorv1typedclient "github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1"
@@ -56,7 +56,6 @@ type containerEngineInterface interface {
5656
pullImage(imageName string) error
5757
putFileToMount(filename string, content []byte) error
5858
stopContainer(containerName string) error
59-
// some container engines have special handlings for different types of containers
6059
runConsoleContainer(containerName string, port string, consoleArgs []string, envVars []envVar) error
6160
runMonitorPlugin(containerName string, consoleContainerName string, nginxConf string, pluginArgs []string) error
6261
containerIsExist(containerName string) (bool, error)
@@ -70,7 +69,7 @@ type dockerLinux struct{}
7069
type dockerMac struct{}
7170

7271
type execActionOnTermInterface interface {
73-
execActionOnTerminationFunction(action postTerminationAction) error
72+
execActionOnTerminationFunction(action postTerminateFunc) error
7473
}
7574

7675
type execActionOnTermStruct struct{}
@@ -101,7 +100,7 @@ const (
101100
PODMAN = "podman"
102101
// Linux name in runtime.GOOS
103102
LINUX = "linux"
104-
// MacOS name in runtime.GOOS
103+
// MACOS name in runtime.GOOS
105104
MACOS = "darwin"
106105

107106
// Environment variable that indicates if open by browser is set as default
@@ -137,12 +136,12 @@ var (
137136

138137
// Pull Secret saving directory
139138
pullSecretConfigDirectory string
140-
141-
ctx, cancel = context.WithCancel(context.Background())
142139
)
143140

144141
func newConsoleOptions() *consoleOptions {
145-
return &consoleOptions{terminationFunction: &execActionOnTermStruct{}}
142+
return &consoleOptions{
143+
terminationFunction: &execActionOnTermStruct{},
144+
}
146145
}
147146

148147
func NewConsoleCmd() *cobra.Command {
@@ -157,7 +156,9 @@ func NewConsoleCmd() *cobra.Command {
157156
You can specify container engine with -c. If not specified, it will lookup the PATH in the order of podman and docker.
158157
`,
159158
SilenceUsage: true,
160-
RunE: ops.run,
159+
RunE: func(cmd *cobra.Command, args []string) error {
160+
return ops.run()
161+
},
161162
}
162163

163164
flags := consoleCmd.Flags()
@@ -205,7 +206,7 @@ func NewConsoleCmd() *cobra.Command {
205206
return consoleCmd
206207
}
207208

208-
func (o *consoleOptions) run(cmd *cobra.Command, argv []string) error {
209+
func (o *consoleOptions) run() error {
209210
err := o.determineOpenBrowser()
210211
if err != nil {
211212
return err
@@ -222,7 +223,6 @@ func (o *consoleOptions) run(cmd *cobra.Command, argv []string) error {
222223
if err != nil {
223224
return err
224225
}
225-
// finialize the console image url
226226
err = o.determineImage(kubeconfig)
227227
if err != nil {
228228
return err
@@ -249,16 +249,14 @@ func (o *consoleOptions) run(cmd *cobra.Command, argv []string) error {
249249
if err != nil {
250250
return err
251251
}
252-
//Perform a cleanup before starting a new console
252+
// Perform a cleanup before starting a new console
253253
err = o.beforeStartCleanUp(ce)
254254
if err != nil {
255255
return err
256256
}
257-
done := make(chan bool)
258-
errs := make(chan error)
259-
260-
go o.runContainers(ce, done, errs)
261257

258+
errs := make(chan error)
259+
go o.runContainers(ce, errs)
262260
if len(errs) != 0 {
263261
err := <-errs
264262
return err
@@ -272,9 +270,8 @@ func (o *consoleOptions) run(cmd *cobra.Command, argv []string) error {
272270
return nil
273271
}
274272

275-
func (o *consoleOptions) runContainers(ce containerEngineInterface, done chan bool, errs chan<- error) {
273+
func (o *consoleOptions) runContainers(ce containerEngineInterface, errs chan<- error) {
276274
if err := o.runConsoleContainer(ce); err != nil {
277-
278275
errs <- err
279276
return
280277
}
@@ -286,8 +283,6 @@ func (o *consoleOptions) runContainers(ce containerEngineInterface, done chan bo
286283
if err := o.printURL(); err != nil {
287284
errs <- err
288285
}
289-
290-
close(done)
291286
}
292287

293288
// Parse environment variables
@@ -374,7 +369,6 @@ func (o *consoleOptions) getContainerEngineImpl() (containerEngineInterface, err
374369
} else if runtime.GOOS == LINUX && containerEngine == DOCKER {
375370
containerEngineImpl = &dockerLinux{}
376371
} else if runtime.GOOS == MACOS && containerEngine == DOCKER {
377-
logger.Warnln("Docker on MacOS is not tested")
378372
containerEngineImpl = &dockerMac{}
379373
}
380374
return containerEngineImpl, nil
@@ -555,7 +549,7 @@ func (o *consoleOptions) runConsoleContainer(ce containerEngineInterface) error
555549

556550
bridgeListen := fmt.Sprintf("http://0.0.0.0:%s", o.port)
557551

558-
envVars := []envVar{}
552+
var envVars []envVar
559553
// Set proxy URL to the container
560554
proxyURL, err := getProxyURL()
561555
if err != nil {
@@ -677,17 +671,19 @@ func (o *consoleOptions) beforeStartCleanUp(ce containerEngineInterface) error {
677671
return nil
678672
}
679673

674+
// cleanUp will first populate the containers needed to clean up, then call the blocking function
675+
// o.terminateFunction, which will block until a system signal is received.
680676
func (o *consoleOptions) cleanUp(ce containerEngineInterface) error {
681677
clusterID, err := getClusterID()
682678
if err != nil {
683679
return err
684680
}
685681

686-
containersToCleanUp := []string{}
682+
var containersToCleanUp []string
687683

688684
// forcing order of removal as the order is not deterministic between container engines
689685
if o.needMonitorPlugin {
690-
logger.Debugln("monitoring plugin is needed, need to clean up monitoring plugin first")
686+
logger.Debugln("adding monitoring plugin to containers for cleanup")
691687
containersToCleanUp = append(containersToCleanUp, fmt.Sprintf("monitoring-plugin-%s", clusterID))
692688
}
693689
containersToCleanUp = append(containersToCleanUp, fmt.Sprintf("console-%s", clusterID))
@@ -698,7 +694,6 @@ func (o *consoleOptions) cleanUp(ce containerEngineInterface) error {
698694
o.terminationFunction = &execActionOnTermStruct{}
699695
}
700696

701-
<-ctx.Done()
702697
err = o.terminationFunction.execActionOnTerminationFunction(func() error {
703698
for _, c := range containersToCleanUp {
704699
exist, err := ce.containerIsExist(c)
@@ -911,9 +906,6 @@ func GetConfigDirectory() (string, error) {
911906

912907
// Update config directory default path
913908
pullSecretConfigDirectory = filepath.Join(home, ".kube/ocm-pull-secret")
914-
if err != nil {
915-
return "", fmt.Errorf("can't modify config directory. Error: %s", err.Error())
916-
}
917909
}
918910

919911
return pullSecretConfigDirectory, nil
@@ -979,24 +971,19 @@ func replaceConsoleURL(containerURL string, userProvidedURL string) (string, err
979971
return u.String(), nil
980972
}
981973

982-
type postTerminationAction func() error
974+
type postTerminateFunc func() error
983975

984976
// keep the program running in frontend and wait for ctrl-c
985-
func (e *execActionOnTermStruct) execActionOnTerminationFunction(action postTerminationAction) error {
977+
func (e *execActionOnTermStruct) execActionOnTerminationFunction(action postTerminateFunc) error {
986978
sigs := make(chan os.Signal, 1)
987979
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
988-
done := make(chan bool, 1)
989980
sig := <-sigs
990-
fmt.Println(sig)
991-
done <- true
992-
err := action()
993-
if err != nil {
994-
return err
995-
}
996-
return nil
981+
fmt.Printf("System signal '%v' received, cleaning up containers and exiting...\n", sig)
982+
983+
return action()
997984
}
998985

999-
// ---- Contianer Engine Implementations ---- //
986+
// ---- Container Engine Implementations ---- //
1000987

1001988
// podman pull - pull the image to local from registry
1002989
// this action is OS independent
@@ -1070,7 +1057,7 @@ func (ce *dockerMac) pullImage(imageName string) error {
10701057
return generalDockerPullImage(imageName)
10711058
}
10721059

1073-
// the shared function for podman to run console container for both linux and macos
1060+
// the shared function for podman to run console container for both linux and macOS
10741061
func podmanRunConsoleContainer(containerName string, port string, consoleArgs []string, envVars []envVar) error {
10751062
_, authFilename, err := fetchPullSecretIfNotExist()
10761063
if err != nil {
@@ -1093,15 +1080,11 @@ func podmanRunConsoleContainer(containerName string, port string, consoleArgs []
10931080
engRunArgs = append(engRunArgs, consoleArgs...)
10941081
logger.WithField("Command", fmt.Sprintf("`%s %s`", PODMAN, strings.Join(engRunArgs, " "))).Infoln("Running container")
10951082

1096-
runCmd := exec.CommandContext(ctx, PODMAN, engRunArgs...)
1097-
defer cancel()
1083+
runCmd := createCommand(PODMAN, engRunArgs...)
10981084
runCmd.Stderr = os.Stderr
10991085
runCmd.Stdout = nil
1100-
err = runCmd.Run()
1101-
if err != nil {
1102-
return err
1103-
}
1104-
return nil
1086+
1087+
return runCmd.Run()
11051088
}
11061089

11071090
func (ce *podmanMac) runConsoleContainer(containerName string, port string, consoleArgs []string, envVars []envVar) error {
@@ -1112,7 +1095,7 @@ func (ce *podmanLinux) runConsoleContainer(containerName string, port string, co
11121095
return podmanRunConsoleContainer(containerName, port, consoleArgs, envVars)
11131096
}
11141097

1115-
// the shared function for docker to run console container for both linux and macos
1098+
// the shared function for docker to run console container for both linux and macOS
11161099
func dockerRunConsoleContainer(containerName string, port string, consoleArgs []string, envVars []envVar) error {
11171100
configDirectory, _, err := fetchPullSecretIfNotExist()
11181101
if err != nil {
@@ -1138,15 +1121,12 @@ func dockerRunConsoleContainer(containerName string, port string, consoleArgs []
11381121
}
11391122
engRunArgs = append(engRunArgs, consoleArgs...)
11401123
logger.WithField("Command", fmt.Sprintf("`%s %s`", DOCKER, strings.Join(engRunArgs, " "))).Infoln("Running container")
1124+
11411125
runCmd := createCommand(DOCKER, engRunArgs...)
11421126
runCmd.Stderr = os.Stderr
11431127
runCmd.Stdout = nil
11441128

1145-
err = runCmd.Run()
1146-
if err != nil {
1147-
return err
1148-
}
1149-
return nil
1129+
return runCmd.Run()
11501130
}
11511131

11521132
func (ce *dockerMac) runConsoleContainer(containerName string, port string, consoleArgs []string, envVars []envVar) error {
@@ -1157,7 +1137,7 @@ func (ce *dockerLinux) runConsoleContainer(containerName string, port string, co
11571137
return dockerRunConsoleContainer(containerName, port, consoleArgs, envVars)
11581138
}
11591139

1160-
// the shared function for podman to run monitoring plugin for both linux and macos
1140+
// the shared function for podman to run monitoring plugin for both linux and macOS
11611141
func podmanRunMonitorPlugin(containerName string, consoleContainerName string, nginxConfPath string, pluginArgs []string) error {
11621142
_, authFilename, err := fetchPullSecretIfNotExist()
11631143
if err != nil {
@@ -1180,11 +1160,7 @@ func podmanRunMonitorPlugin(containerName string, consoleContainerName string, n
11801160
runCmd.Stderr = os.Stderr
11811161
runCmd.Stdout = nil
11821162

1183-
err = runCmd.Run()
1184-
if err != nil {
1185-
return err
1186-
}
1187-
return nil
1163+
return runCmd.Run()
11881164
}
11891165

11901166
func (ce *podmanMac) runMonitorPlugin(containerName string, consoleContainerName string, nginxConf string, pluginArgs []string) error {
@@ -1197,8 +1173,8 @@ func (ce *podmanLinux) runMonitorPlugin(containerName string, consoleContainerNa
11971173
return podmanRunMonitorPlugin(containerName, consoleContainerName, nginxConfPath, pluginArgs)
11981174
}
11991175

1200-
// the shared function for docker to run monitoring plugin for both linux and macos
1201-
func dockerRunMonitorPlugin(containerName string, consoleContainerName string, nginxConfPath string, pluginArgs []string) error {
1176+
// the shared function for docker to run monitoring plugin for both linux and macOS
1177+
func dockerRunMonitorPlugin(containerName string, _ string, nginxConfPath string, pluginArgs []string) error {
12021178
configDirectory, _, err := fetchPullSecretIfNotExist()
12031179
if err != nil {
12041180
return err
@@ -1220,11 +1196,7 @@ func dockerRunMonitorPlugin(containerName string, consoleContainerName string, n
12201196
runCmd.Stderr = os.Stderr
12211197
runCmd.Stdout = nil
12221198

1223-
err = runCmd.Run()
1224-
if err != nil {
1225-
return err
1226-
}
1227-
return nil
1199+
return runCmd.Run()
12281200
}
12291201

12301202
func (ce *dockerLinux) runMonitorPlugin(containerName string, consoleContainerName string, nginxConf string, pluginArgs []string) error {
@@ -1385,7 +1357,7 @@ func (ce *podmanLinux) stopContainer(containerName string) error {
13851357
return generalStopContainer(PODMAN, containerName)
13861358
}
13871359

1388-
// podman-stop for MacOS
1360+
// podman-stop for macOS
13891361
func (ce *podmanMac) stopContainer(containerName string) error {
13901362
return generalStopContainer(PODMAN, containerName)
13911363
}
@@ -1395,7 +1367,7 @@ func (ce *dockerLinux) stopContainer(containerName string) error {
13951367
return generalStopContainer(DOCKER, containerName)
13961368
}
13971369

1398-
// docker-stop for MacOS
1370+
// docker-stop for macOS
13991371
func (ce *dockerMac) stopContainer(containerName string) error {
14001372
return generalStopContainer(DOCKER, containerName)
14011373
}
@@ -1405,7 +1377,7 @@ func (ce *podmanLinux) containerIsExist(containerName string) (bool, error) {
14051377
return generalContainerIsExist(PODMAN, containerName)
14061378
}
14071379

1408-
// podman-exist for MacOS
1380+
// podman-exist for macOS
14091381
func (ce *podmanMac) containerIsExist(containerName string) (bool, error) {
14101382
return generalContainerIsExist(PODMAN, containerName)
14111383
}
@@ -1415,7 +1387,7 @@ func (ce *dockerLinux) containerIsExist(containerName string) (bool, error) {
14151387
return generalContainerIsExist(DOCKER, containerName)
14161388
}
14171389

1418-
// docker-exist for MacOS
1390+
// docker-exist for macOS
14191391
func (ce *dockerMac) containerIsExist(containerName string) (bool, error) {
14201392
return generalContainerIsExist(DOCKER, containerName)
14211393
}

cmd/ocm-backplane/console/console_suite_test.go

-13
This file was deleted.

0 commit comments

Comments
 (0)