Skip to content

Commit

Permalink
Merge pull request #1434 from kubeshop/olelensmar/fix/apply-on-ubuntu
Browse files Browse the repository at this point in the history
  • Loading branch information
olensmar authored Mar 8, 2022
2 parents a4c33a6 + d3ed55e commit 2885659
Show file tree
Hide file tree
Showing 32 changed files with 418 additions and 405 deletions.
99 changes: 46 additions & 53 deletions electron/commands.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,21 @@
import {BrowserWindow, dialog} from 'electron';

import {execSync} from 'child_process';
import {spawn} from 'child_process';
import {AnyAction} from 'redux';
import {VM} from 'vm2';

import {NewVersionCode} from '@models/appconfig';

import {updateNewVersion} from '@redux/reducers/appConfig';
import {InterpolateTemplateOptions} from '@redux/services/templates';
import {KustomizeCommandOptions} from '@redux/thunks/previewKustomization';

import {FileExplorerOptions, FileOptions} from '@atoms/FileExplorer/FileExplorerOptions';

import {PROCESS_ENV} from '@utils/env';
import {CommandOptions, CommandResult} from '@utils/command';
import {ensureMainThread} from '@utils/thread';

import autoUpdater from './auto-update';

/**
* called by thunk to preview a kustomization
*/

export const runKustomize = (options: KustomizeCommandOptions, event: Electron.IpcMainEvent) => {
try {
let cmd = options.kustomizeCommand === 'kubectl' ? 'kubectl kustomize ' : 'kustomize build ';
if (options.enableHelm) {
cmd += '--enable-helm ';
}

let stdout = execSync(`${cmd} "${options.folder}"`, {
env: {
NODE_ENV: PROCESS_ENV.NODE_ENV,
PUBLIC_URL: PROCESS_ENV.PUBLIC_URL,
PATH: PROCESS_ENV.PATH,
},
maxBuffer: 1024 * 1024 * 10,
windowsHide: true,
});

event.sender.send('kustomize-result', {stdout: stdout.toString()});
} catch (e: any) {
event.sender.send('kustomize-result', {error: e.toString()});
}
};

/**
* prompts to select a file using the native dialogs
*/
Expand Down Expand Up @@ -100,29 +73,6 @@ export const saveFileDialog = (event: Electron.IpcMainInvokeEvent, options: File
return dialog.showSaveDialogSync(dialogOptions);
};

/**
* called by thunk to preview a helm chart with values file
*/

export const runHelm = (args: any, event: Electron.IpcMainEvent) => {
try {
let stdout = execSync(args.helmCommand, {
env: {
NODE_ENV: PROCESS_ENV.NODE_ENV,
PUBLIC_URL: PROCESS_ENV.PUBLIC_URL,
KUBECONFIG: args.kubeconfig,
PATH: PROCESS_ENV.PATH,
},
maxBuffer: 1024 * 1024 * 10,
windowsHide: true,
});

event.sender.send('helm-result', {stdout: stdout.toString()});
} catch (e: any) {
event.sender.send('helm-result', {error: e.toString()});
}
};

/**
* Checks for a new version of monokle
*/
Expand Down Expand Up @@ -180,3 +130,46 @@ export const interpolateTemplate = (args: InterpolateTemplateOptions, event: Ele

event.sender.send('interpolate-vanilla-template-result', result);
};

/**
* called by the renderer thread to run a command and capture its output
*/

export const runCommand = (options: CommandOptions, event: Electron.IpcMainEvent) => {
ensureMainThread();

const result: CommandResult = {exitCode: null, signal: null};

try {
const child = spawn(options.cmd, options.args, {
env: {
...options.env,
...process.env,
},
shell: true,
windowsHide: true,
});

if (options.input) {
child.stdin.write(options.input);
child.stdin.end();
}

child.on('exit', (code, signal) => {
result.exitCode = code;
result.signal = signal && signal.toString();
event.sender.send('command-result', result);
});

child.stdout.on('data', data => {
result.stdout = result.stdout ? result.stdout + data.toString() : data.toString();
});

child.stderr.on('data', data => {
result.stderr = result.stderr ? result.stderr + data.toString() : data.toString();
});
} catch (e: any) {
result.error = e.message;
event.sender.send('command-result', result);
}
};
33 changes: 16 additions & 17 deletions electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
ROOT_FILE_ENTRY,
} from '@constants/constants';
import {DOWNLOAD_PLUGIN, DOWNLOAD_PLUGIN_RESULT, DOWNLOAD_TEMPLATE, DOWNLOAD_TEMPLATE_RESULT, DOWNLOAD_TEMPLATE_PACK, DOWNLOAD_TEMPLATE_PACK_RESULT, UPDATE_EXTENSIONS, UPDATE_EXTENSIONS_RESULT} from '@constants/ipcEvents';
import {checkMissingDependencies} from '@utils/index';
import ElectronStore from 'electron-store';
import {
changeCurrentProjectName,
Expand All @@ -42,7 +41,6 @@ import {K8sResource} from '@models/k8sresource';
import {isInPreviewModeSelector, kubeConfigContextSelector, unsavedResourcesSelector, activeProjectSelector} from '@redux/selectors';
import {HelmChart, HelmValuesFile} from '@models/helm';
import log from 'loglevel';
import {PROCESS_ENV} from '@utils/env';
import asyncLib from "async";

import {createMenu, getDockMenu} from './menu';
Expand All @@ -53,9 +51,7 @@ import {AlertEnum, AlertType} from '@models/alert';
import {setAlert} from '@redux/reducers/alert';
import {
checkNewVersion,
interpolateTemplate,
runHelm,
runKustomize,
interpolateTemplate, runCommand,
saveFileDialog,
selectFileDialog,
} from '@root/electron/commands';
Expand All @@ -70,17 +66,25 @@ import {downloadTemplate, downloadTemplatePack, loadTemplatePackMap, loadTemplat
import {AnyTemplate, TemplatePack} from '@models/template';
import {AnyPlugin} from '@models/plugin';
import {AnyExtension, DownloadPluginResult, DownloadTemplatePackResult, DownloadTemplateResult, UpdateExtensionsResult} from '@models/extension';
import {KustomizeCommandOptions} from '@redux/thunks/previewKustomization';
import { askActionConfirmation, convertRecentFilesToRecentProjects, getSerializedProcessEnv, saveInitialK8sSchema, setProjectsRootFolder, setDeviceID, initNucleus } from './utils';
import {
askActionConfirmation,
checkMissingDependencies,
convertRecentFilesToRecentProjects,
getSerializedProcessEnv,
initNucleus,
saveInitialK8sSchema,
setDeviceID,
setProjectsRootFolder,
} from './utils';
import {InterpolateTemplateOptions} from '@redux/services/templates';
import {StartupFlags} from '@utils/startupFlag';
import {ProjectNameChange, StorePropagation} from '@utils/global-electron-store';
import {CommandOptions} from '@utils/command';

Object.assign(console, ElectronLog.functions);

const {MONOKLE_RUN_AS_NODE} = process.env;

const isDev = PROCESS_ENV.NODE_ENV === 'development';
const isDev = process.env.NODE_ENV === 'development';

const userHomeDir = app.getPath('home');
const userDataDir = app.getPath('userData');
Expand Down Expand Up @@ -239,20 +243,16 @@ ipcMain.on('interpolate-vanilla-template', (event:any, args: InterpolateTemplate
interpolateTemplate(args, event);
});

ipcMain.on('run-kustomize', (event:any, cmdOptions: KustomizeCommandOptions) => {
runKustomize(cmdOptions, event);
});

ipcMain.handle('select-file', async (event:any, options: FileExplorerOptions) => {
ipcMain.handle('select-file', async (event, options: FileExplorerOptions) => {
return selectFileDialog(event, options);
});

ipcMain.handle('save-file', async (event:any, options: FileOptions) => {
return saveFileDialog(event, options);
});

ipcMain.on('run-helm', (event, args: any) => {
runHelm(args, event);
ipcMain.on('run-command', (event, args: CommandOptions) => {
runCommand(args, event);
});

ipcMain.on('app-version', event => {
Expand Down Expand Up @@ -447,7 +447,6 @@ export const createWindow = (givenPath?: string) => {
return win;
};


export const openApplication = async (givenPath?: string) => {
await app.whenReady();

Expand Down
9 changes: 4 additions & 5 deletions electron/src/initKubeconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ import {setKubeConfig} from '@redux/reducers/appConfig';
import {monitorKubeConfig} from '@redux/services/kubeConfigMonitor';

import electronStore from '@utils/electronStore';
import {PROCESS_ENV} from '@utils/env';

function initKubeconfig(dispatch: (action: AnyAction) => void, userHomeDir: string) {
if (PROCESS_ENV.KUBECONFIG) {
const envKubeconfigParts = PROCESS_ENV.KUBECONFIG.split(path.delimiter);
if (process.env.KUBECONFIG) {
const envKubeconfigParts = process.env.KUBECONFIG.split(path.delimiter);
if (envKubeconfigParts.length > 1) {
dispatch(setKubeConfig(getKubeConfigContext(envKubeconfigParts[0])));
monitorKubeConfig(envKubeconfigParts[0], dispatch);
Expand All @@ -28,8 +27,8 @@ function initKubeconfig(dispatch: (action: AnyAction) => void, userHomeDir: stri
})
);
} else {
dispatch(setKubeConfig(getKubeConfigContext(PROCESS_ENV.KUBECONFIG)));
monitorKubeConfig(PROCESS_ENV.KUBECONFIG, dispatch);
dispatch(setKubeConfig(getKubeConfigContext(process.env.KUBECONFIG)));
monitorKubeConfig(process.env.KUBECONFIG, dispatch);
}
return;
}
Expand Down
24 changes: 21 additions & 3 deletions electron/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {dialog} from 'electron';

import {AnyAction} from '@reduxjs/toolkit';

import {execSync} from 'child_process';
import {existsSync, mkdirSync, writeFileSync} from 'fs';
import gitUrlParse from 'git-url-parse';
import _ from 'lodash';
import log from 'loglevel';
import {machineIdSync} from 'node-machine-id';
import Nucleus from 'nucleus-nodejs';
import path, {join} from 'path';
Expand All @@ -17,7 +19,6 @@ import {createProject} from '@redux/reducers/appConfig';
import {loadResource} from '@redux/services';

import electronStore from '@utils/electronStore';
import {PROCESS_ENV} from '@utils/env';

const GITHUB_REPOSITORY_REGEX = /^https:\/\/github.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+/i;

Expand Down Expand Up @@ -106,7 +107,7 @@ export const setDeviceID = (deviceID: string) => {

export const getSerializedProcessEnv = () => {
const serializedProcessEnv: Record<string, string> = {};
const processEnv = _.isObject(PROCESS_ENV) ? PROCESS_ENV : _.isObject(process.env) ? process.env : {};
const processEnv = _.isObject(process.env) ? process.env : {};
Object.entries(processEnv).forEach(([key, value]) => {
if (typeof value === 'string') {
serializedProcessEnv[key] = value;
Expand Down Expand Up @@ -168,8 +169,25 @@ export function askActionConfirmation({
return choice === 0;
}

export const checkMissingDependencies = (dependencies: Array<string>): Array<string> => {
log.info(`checking dependencies with process path: ${process.env.PATH}`);

return dependencies.filter(d => {
try {
execSync(d, {
env: process.env,
windowsHide: true,
});
return false;
} catch (e: any) {
return true;
}
});
};


export const initNucleus = (isDev: boolean, app: any) => {
Nucleus.init(PROCESS_ENV.NUCLEUS_SH_APP_ID || '6218cf3ef5e5d2023724d89b', {
Nucleus.init(process.env.NUCLEUS_SH_APP_ID || '6218cf3ef5e5d2023724d89b', {
disableInDev: false,
disableTracking: Boolean(electronStore.get('appConfig.disableEventTracking')),
disableErrorReports: true,
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"craco-alias": "3.0.1",
"craco-less": "1.20.0",
"cross-env": "7.0.3",
"electron": "17.0.1",
"electron": "17.1.1",
"electron-builder": "23.0.0-alpha.3",
"electron-notarize": "1.1.1",
"electron-reload": "2.0.0-alpha.1",
Expand Down Expand Up @@ -84,7 +84,7 @@
},
"dependencies": {
"@ant-design/icons": "4.7.0",
"@kubernetes/client-node": "0.16.2",
"@kubernetes/client-node": "0.16.3",
"@reduxjs/toolkit": "1.7.2",
"@rjsf/antd": "3.2.1",
"@rjsf/core": "3.2.1",
Expand Down Expand Up @@ -133,7 +133,6 @@
"reselect": "4.1.5",
"runtypes": "6.5.0",
"semver": "7.3.5",
"shell-path": "2.1.0",
"shelljs": "0.8.5",
"strip-ansi": "6.0.1",
"styled-components": "5.3.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import styled from 'styled-components';
import {K8sResource} from '@models/k8sresource';

import {useAppSelector} from '@redux/hooks';
import {kubeConfigContextSelector, kubeConfigPathSelector} from '@redux/selectors';

import {useTargetClusterNamespaces} from '@hooks/useTargetClusterNamespaces';

Expand Down Expand Up @@ -60,9 +59,6 @@ interface IProps {
const ModalConfirmWithNamespaceSelect: React.FC<IProps> = props => {
const {isVisible, resources = [], title, onCancel, onOk} = props;

const kubeConfigPath = useAppSelector(kubeConfigPathSelector);
const kubeConfigContext = useAppSelector(kubeConfigContextSelector);

const configState = useAppSelector(state => state.config);
const {defaultNamespace, defaultOption} = getDefaultNamespaceForApply(resources);
const [namespaces] = useTargetClusterNamespaces();
Expand Down Expand Up @@ -99,7 +95,7 @@ const ModalConfirmWithNamespaceSelect: React.FC<IProps> = props => {
} else if (selectedOption === 'none') {
onOk();
}
}, [kubeConfigContext, createNamespaceName, kubeConfigPath, selectedNamespace, selectedOption, onOk, configState]);
}, [createNamespaceName, selectedNamespace, selectedOption, onOk, configState]);

useEffect(() => {
if (defaultOption && defaultOption === 'none') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const PreviwConfigurationDetails: React.FC = () => {

const builtCommand = useMemo(() => {
if (!previewConfiguration || !helmChart) {
return '';
return [''];
}
return buildHelmCommand(
helmChart,
Expand Down Expand Up @@ -72,7 +72,7 @@ const PreviwConfigurationDetails: React.FC = () => {
</Breadcrumb>
)}
<Text code copyable>
{builtCommand}
{builtCommand.join(' ')}
</Text>
</Container>
);
Expand Down
6 changes: 3 additions & 3 deletions src/components/molecules/ResourceDiff/ResourceDiff.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {K8sResource} from '@models/k8sresource';

import {useAppDispatch, useAppSelector} from '@redux/hooks';
import {updateResource} from '@redux/reducers/main';
import {kubeConfigContextSelector, kubeConfigPathSelector} from '@redux/selectors';
import {currentConfigSelector, kubeConfigContextSelector} from '@redux/selectors';
import {isKustomizationResource} from '@redux/services/kustomize';
import {applyResource} from '@redux/thunks/applyResource';

Expand Down Expand Up @@ -93,7 +93,7 @@ const ResourceDiff = (props: {
const resourceMap = useAppSelector(state => state.main.resourceMap);
const previewType = useAppSelector(state => state.main.previewType);
const fileMap = useAppSelector(state => state.main.fileMap);
const kubeConfigPath = useAppSelector(kubeConfigPathSelector);
const projectConfig = useAppSelector(currentConfigSelector);
const kubeConfigContext = useAppSelector(kubeConfigContextSelector);
const [shouldDiffIgnorePaths, setShouldDiffIgnorePaths] = useState<boolean>(true);

Expand Down Expand Up @@ -166,7 +166,7 @@ const ResourceDiff = (props: {
onApply();
}

applyResource(localResource.id, resourceMap, fileMap, dispatch, kubeConfigPath, kubeConfigContext, namespace, {
applyResource(localResource.id, resourceMap, fileMap, dispatch, projectConfig, kubeConfigContext, namespace, {
isClusterPreview: previewType === 'cluster',
shouldPerformDiff: true,
isInClusterDiff,
Expand Down
Loading

0 comments on commit 2885659

Please sign in to comment.