Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why change this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible we start tests from xpack folder instead of root, this way is more robust.

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