Skip to content

Commit

Permalink
[Code] setup multi-code mode by config (#34988)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacedragon authored and zfy0701 committed Apr 15, 2019
1 parent a17a9e9 commit 38b9fa6
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 183 deletions.
1 change: 0 additions & 1 deletion x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@
"@types/tar-fs": "^1.16.1",
"@types/tinycolor2": "^1.4.1",
"@types/uuid": "^3.4.4",
"@types/wreck": "^14.0.0",
"abab": "^1.0.4",
"ansi-colors": "^3.0.5",
"ansicolors": "0.3.2",
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/code/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const code = (kibana: any) =>
maxWorkspace: Joi.number().default(5), // max workspace folder for each language server
disableIndexScheduler: Joi.boolean().default(true), // Temp option to disable index scheduler.
enableGlobalReference: Joi.boolean().default(false), // Global reference as optional feature for now
codeNode: Joi.boolean().default(false),
codeNodeUrl: Joi.string(),
}).default();
},
init,
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/code/public/components/main/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,11 @@ class CodeContent extends React.PureComponent<Props> {
}
const currentTree = this.props.currentTree;
if (
this.props.file &&
currentTree &&
(currentTree.type === FileTreeItemType.File || currentTree.type === FileTreeItemType.Link)
) {
const { isUnsupported, isOversize, isImage, lang } = this.props.file!;
const { isUnsupported, isOversize, isImage, lang } = this.props.file;
const isMarkdown = lang === LANG_MD;
const isText = !isUnsupported && !isOversize && !isImage;

Expand Down
39 changes: 18 additions & 21 deletions x-pack/plugins/code/server/__tests__/multi_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,26 @@
import getPort from 'get-port';
import { resolve } from 'path';
import { Root } from 'src/core/server/root';
import { createRootWithCorePlugins, request, startTestServers } from 'src/test_utils/kbn_server';
import {
createRootWithCorePlugins,
request,
startTestServers,
} from '../../../../../src/test_utils/kbn_server';

describe('code in multiple nodes', () => {
const codeNodeUuid = 'c4add484-0cba-4e05-86fe-4baa112d9e53';
let port: number;
const nonodeNodeUuid = '22b75e04-0e50-4647-9643-6b1b1d88beaf';
let codePort: number;
let nonCodePort: number;
let codeNode: Root;
let nonCodeNode: Root;

let servers: any;
const pluginPaths = resolve(__dirname, '../../../../../node_modules/x-pack');
const pluginPaths = resolve(__dirname, '../../../../../x-pack');

async function startServers() {
port = await getPort();
codePort = await getPort();
nonCodePort = await getPort();
servers = await startTestServers({
adjustTimeout: t => {
// @ts-ignore
Expand All @@ -29,16 +36,13 @@ describe('code in multiple nodes', () => {
kbn: {
server: {
uuid: codeNodeUuid,
port,
port: codePort,
},
plugins: { paths: [pluginPaths] },
xpack: {
upgrade_assistant: {
enabled: false,
},
code: {
codeNode: true,
},
security: {
enabled: false,
},
Expand All @@ -52,12 +56,16 @@ describe('code in multiple nodes', () => {

async function startNonCodeNodeKibana() {
const setting = {
server: {
port: nonCodePort,
uuid: nonodeNodeUuid,
},
plugins: { paths: [pluginPaths] },
xpack: {
upgrade_assistant: {
enabled: false,
},
code: { codeNode: false },
code: { codeNodeUrl: `http://localhost:${codePort}` },
security: {
enabled: false,
},
Expand Down Expand Up @@ -93,22 +101,11 @@ describe('code in multiple nodes', () => {

it('Non-code node setup should fail if code node is shutdown', async () => {
await codeNode.shutdown();
await delay(2000);
await request.get(nonCodeNode, '/api/code/setup').expect(502);
await codeNode.setup();
await delay(2000);
await request.get(nonCodeNode, '/api/code/setup').expect(200);
// @ts-ignore
}).timeout(20000);

it('cluster uuid should equals Code node uuid', async () => {
const url = `http://localhost:${port}`;
await request.get(codeNode, '/api/code/cluster').expect(200, {
uuid: codeNodeUuid,
url,
});
await request.get(nonCodeNode, '/api/code/cluster').expect(200, {
uuid: codeNodeUuid,
url,
});
});
});
79 changes: 0 additions & 79 deletions x-pack/plugins/code/server/code_node_client.ts

This file was deleted.

68 changes: 24 additions & 44 deletions x-pack/plugins/code/server/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
*/

import { Server } from 'hapi';
import fetch from 'node-fetch';
import { checkRepos } from './check_repos';
import { clientWithInternalUser, CodeNodeInfo } from './code_node_client';
import { LspIndexerFactory, RepositoryIndexInitializerFactory, tryMigrateIndices } from './indexer';
import { EsClient, Esqueue } from './lib/esqueue';
import { Logger } from './log';
Expand Down Expand Up @@ -64,71 +64,51 @@ function getServerUuid(server: Server): Promise<string> {
return Promise.resolve(uid);
}

async function getCodeNodeUuid(url: string, log: Logger) {
const res = await fetch(`${url}/api/stats`, {});
if (res.ok) {
return (await res.json()).kibana.uuid;
}

log.info(`Access code node ${url} failed, try again later.`);
return null;
}

export function init(server: Server, options: any) {
const log = new Logger(server);
const serverOptions = new ServerOptions(options, server.config());
// @ts-ignore
const kbnServer = this.kbnServer;
kbnServer.ready().then(async () => {
const serverUuid = await retryUntilAvailable(() => getServerUuid(server), 50);
const codeNodeClient = await clientWithInternalUser(server);
// enable security check in routes
enableSecurity(server);
if (serverOptions.codeNode) {
let info = await codeNodeClient.getCodeNodeInfo();
if (!info) {
let url: string = server.info.uri;
const serverHost = server.config().get('server.host');
if (serverHost !== undefined && serverHost !== 'localhost') {
const serverPort = server.config().get('server.port');
const schema = server.config().get('server.ssl.enabled') ? 'https' : 'http';
let basePath: string = server.config().get('server.basePath') || '';
if (!basePath.startsWith('/')) {
basePath = '/' + basePath;
}
url = `${schema}://${serverHost}:${serverPort}}${basePath}`;
}
info = await codeNodeClient.createNodeInfo({
uuid: serverUuid,
url,
});
}
if (info.uuid === serverUuid) {
const codeNodeUrl = serverOptions.codeNodeUrl;
if (codeNodeUrl) {
const codeNodeUuid = (await retryUntilAvailable(
async () => await getCodeNodeUuid(codeNodeUrl, log),
5000
)) as string;
if (codeNodeUuid === serverUuid) {
await initCodeNode(server, serverOptions, log);
} else {
const adminCluster = server.plugins.elasticsearch.getCluster('admin');
// @ts-ignore
const esUrl = adminCluster.clusterClient.config.hosts[0];
log.error(
`A code node with different uuid:${info.uuid} is already registered as code nodes.
1. If this kibana node should be a non-code node, then please set "xpack.code.codeNode" to false in kibana.yml.
2. If you want to replace the code-node to this kibana node, then please delete the old info by execute:
curl --request DELETE --url ${esUrl}/.code_node/_doc/code-node-info
`
);
await initNonCodeNode(info, server, serverOptions, log);
await initNonCodeNode(codeNodeUrl, server, serverOptions, log);
}
} else {
const info = await retryUntilAvailable(
async () => await codeNodeClient.getCodeNodeInfo(),
50
);
await initNonCodeNode(info!, server, serverOptions, log);
// codeNodeUrl not set, single node mode
await initCodeNode(server, serverOptions, log);
}
});
}

async function initNonCodeNode(
info: CodeNodeInfo,
url: string,
server: Server,
serverOptions: ServerOptions,
log: Logger
) {
log.info(
`Initializing Code plugin as non-code node, redirecting all code requests to ${info.url}`
);

redirectRoute(server, info.url, log);
log.info(`Initializing Code plugin as non-code node, redirecting all code requests to ${url}`);
redirectRoute(server, url, log);
}

async function initCodeNode(server: Server, serverOptions: ServerOptions, log: Logger) {
Expand Down
26 changes: 1 addition & 25 deletions x-pack/plugins/code/server/routes/redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,14 @@
*/

import hapi from 'hapi';
import url from 'url';
import wreck from 'wreck';
import { Logger } from '../log';

export const BASE_PLACEHOLDER = '/{baseUrl}';

export async function mainNodeBaseUrl(redirectUrl: string) {
const u = url.parse(redirectUrl);
const res = await wreck.request('HEAD', '/', {
baseUrl: `${u.protocol}//${u.host}`,
});
if (res.statusCode === 302 && res.headers.location) {
return res.headers.location;
} else {
// no base url?
return '';
}
}

export function redirectRoute(server: hapi.Server, redirect: string, log: Logger) {
let redirectUrl = redirect;
const hasBaseUrl = redirectUrl.includes(BASE_PLACEHOLDER);
export function redirectRoute(server: hapi.Server, redirectUrl: string, log: Logger) {
const proxyHandler = {
proxy: {
passThrough: true,
async mapUri(request: hapi.Request) {
let uri;
if (hasBaseUrl) {
// send a head request to find main node's base url;
const baseUrl = await mainNodeBaseUrl(redirectUrl);
redirectUrl = redirect.replace(BASE_PLACEHOLDER, baseUrl);
}
uri = `${redirectUrl}${request.path}`;
if (request.url.search) {
uri += request.url.search;
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/code/server/server_options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class ServerOptions {

public readonly enabled: boolean = this.options.enabled;

public readonly codeNode: boolean = this.options.codeNode;
public readonly codeNodeUrl: string = this.options.codeNodeUrl;

constructor(private options: any, private config: any) {}
}
1 change: 0 additions & 1 deletion x-pack/test/functional/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ export default async function ({ readConfigFile }) {
'--xpack.xpack_main.telemetry.enabled=false',
'--xpack.maps.showMapsInspectorAdapter=true',
'--xpack.security.encryptionKey="wuGNaIhoMpk5sO4UBxgr3NyW1sFcLgIf"', // server restarts should not invalidate active sessions
'--xpack.code.codeNode="true"',
],
},
uiSettings: {
Expand Down
9 changes: 0 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3634,15 +3634,6 @@
resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-2.0.14.tgz#5afbdd8374de9ff8ad752cb03ab9f225f7c2ee24"
integrity sha1-Wvvdg3Ten/itdSywOrnyJffC7iQ=

"@types/wreck@^14.0.0":
version "14.0.0"
resolved "https://registry.yarnpkg.com/@types/wreck/-/wreck-14.0.0.tgz#8bf39fd789d32af63176bee5eb5705108cd8be5e"
integrity sha512-cxA8o5fGbXg2e/UUoA7z8lMaEw4CwxvJW1Fv+E8xP/n2MOzRdeQUX+e7aUxgr1ganECiIQXUka0OwwKR2ixo1w==
dependencies:
"@types/boom" "*"
"@types/events" "*"
"@types/node" "*"

"@types/write-pkg@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@types/write-pkg/-/write-pkg-3.1.0.tgz#f58767f4fb9a6a3ad8e95d3e9cd1f2d026ceab26"
Expand Down

0 comments on commit 38b9fa6

Please sign in to comment.