@@ -7,6 +7,7 @@ const { EventEmitter } = require('events');
77const fs = require ( 'fs' ) ;
88const pth = require ( 'path' ) ;
99const electron = require ( 'electron' ) ;
10+ const yaml = require ( 'yaml' ) ;
1011const k8s = require ( '@kubernetes/client-node' ) ;
1112const kubectl = require ( '../k8s-engine/kubectl.js' ) ;
1213const kubeconfig = require ( '../config/kubeconfig.js' ) ;
@@ -83,17 +84,60 @@ export class Tray extends EventEmitter {
8384 if ( ! kubeconfigPath ) {
8485 throw new Error ( 'No kubeconfig path found' ) ;
8586 }
86- fs . watch ( kubeconfigPath , ( ) => {
87- this . updateContexts ( ) ;
88- const contextMenu = electron . Menu . buildFromTemplate ( this . #contextMenuItems) ;
87+ this . buildFromConfig ( kubeconfigPath ) ;
88+ const watcher = fs . watch ( kubeconfigPath ) ;
8989
90- this . #trayMenu. setContextMenu ( contextMenu ) ;
90+ watcher . on ( 'error' , ( code , signal ) => {
91+ console . log ( `Failed to fs.watch ${ kubeconfigPath } : code: ${ code } , signal: ${ signal } ` ) ;
92+ } ) ;
93+ watcher . on ( 'change' , ( eventType , _ ) => {
94+ if ( eventType === 'rename' && ! kubeconfig . hasAccess ( kubeconfigPath ) ) {
95+ // File doesn't exist. Wait for it to be recreated
96+ return ;
97+ }
98+ this . buildFromConfig ( kubeconfigPath ) ;
9199 } ) ;
92100
93101 this . on ( 'k8s-check-state' , this . k8sStateChanged . bind ( this ) ) ;
94102 this . on ( 'settings-update' , this . settingsChanged . bind ( this ) ) ;
95103 }
96104
105+ buildFromConfig ( configPath ) {
106+ if ( ! kubeconfig . hasAccess ( configPath ) ) {
107+ return ;
108+ }
109+
110+ try {
111+ let parsedConfig ;
112+ const contents = fs . readFileSync ( configPath ) . toString ( ) ;
113+
114+ if ( contents . length === 0 ) {
115+ console . log ( 'Config file is empty, will try to process it later' ) ;
116+
117+ return ;
118+ }
119+
120+ try {
121+ parsedConfig = yaml . parse ( contents ) ;
122+ } catch ( err ) {
123+ console . log ( `yaml parse failure: ${ err } on kubeconfig: contents ${ contents } ., will retry later.` ) ;
124+ parsedConfig = null ;
125+ }
126+
127+ if ( ( parsedConfig ?. clusters || [ ] ) . length === 0 ) {
128+ console . log ( 'Config file has no clusters, will retry later' ) ;
129+
130+ return ;
131+ }
132+ this . updateContexts ( ) ;
133+ const contextMenu = electron . Menu . buildFromTemplate ( this . #contextMenuItems) ;
134+
135+ this . #trayMenu. setContextMenu ( contextMenu ) ;
136+ } catch ( err ) {
137+ console . log ( `Error trying to update context menu: ${ err } ` ) ;
138+ }
139+ }
140+
97141 /**
98142 * Called when the Kubernetes cluster state has changed.
99143 * @param {State } state The new cluster state.
0 commit comments